summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c19
-rw-r--r--generic/tclIOCmd.c16
2 files changed, 32 insertions, 3 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 534060b..f198474 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: %Z% $Id: tclIO.c,v 1.2 1998/06/09 13:08:16 stanton Exp $
+ * SCCS: %Z% $Id: tclIO.c,v 1.3 1998/06/27 18:10:15 welch Exp $
*/
#include "tclInt.h"
@@ -4519,7 +4519,14 @@ Tcl_NotifyChannel(channel, mask)
ChannelHandler *chPtr;
NextChannelHandler nh;
- Tcl_Preserve((ClientData)chanPtr);
+ /*
+ * Prevent the event handler from deleting the channel by incrementing
+ * the channel's ref count. Case in point: ChannelEventScriptInvoker()
+ * was evaling a script (owned by the channel) which caused the channel
+ * to be closed and then the byte codes no longer existed.
+ */
+
+ Tcl_RegisterChannel((Tcl_Interp *) NULL, channel);
/*
* If we are flushing in the background, be sure to call FlushChannel
@@ -4566,7 +4573,13 @@ Tcl_NotifyChannel(channel, mask)
if (chanPtr->typePtr != NULL) {
UpdateInterest(chanPtr);
}
- Tcl_Release((ClientData)chanPtr);
+
+ /*
+ * No longer need to protect the channel from being deleted.
+ * After this point it is unsafe to use the value of "channel".
+ */
+
+ Tcl_UnregisterChannel((Tcl_Interp *) NULL, channel);
nestedHandlerPtr = nh.nestedHandlerPtr;
}
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 5640b47..88a299a 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -1238,12 +1238,28 @@ AcceptCallbackProc(callbackData, chan, address, port)
TclFormatInt(portBuf, port);
Tcl_RegisterChannel(interp, chan);
+
+ /*
+ * Artificially bump the refcount to protect the channel from
+ * being deleted while the script is being evaluated.
+ */
+
+ Tcl_RegisterChannel((Tcl_Interp *) NULL, chan);
+
result = Tcl_VarEval(interp, script, " ", Tcl_GetChannelName(chan),
" ", address, " ", portBuf, (char *) NULL);
if (result != TCL_OK) {
Tcl_BackgroundError(interp);
Tcl_UnregisterChannel(interp, chan);
}
+
+ /*
+ * Decrement the artificially bumped refcount. After this it is
+ * not safe anymore to use "chan", because it may now be deleted.
+ */
+
+ Tcl_UnregisterChannel((Tcl_Interp *) NULL, chan);
+
Tcl_Release((ClientData) interp);
Tcl_Release((ClientData) script);
} else {