summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2020-04-01 11:54:27 (GMT)
committerdgp <dgp@users.sourceforge.net>2020-04-01 11:54:27 (GMT)
commit14c6f5491be3cd441df1f7142510835c67f78e9d (patch)
tree2154042e4fc5ed59be9173811bb3f8a0803d8d40 /generic
parentf8ae8cc375adc04ed8d810255e0d282cce9ae35e (diff)
parentf394d8c0d4ef97cd0aebf1ce7de1ecb86a50ba9d (diff)
downloadtcl-14c6f5491be3cd441df1f7142510835c67f78e9d.zip
tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.gz
tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.bz2
merge 8.6
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index d65f6e6..edce09b 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -3219,6 +3219,9 @@ CutChannel(
*/
ChanThreadAction((Channel *) chan, TCL_CHANNEL_THREAD_REMOVE);
+
+ /* Channel is not managed by any thread */
+ statePtr->managingThread = NULL;
}
void
@@ -3263,6 +3266,9 @@ Tcl_CutChannel(
for (; chanPtr != NULL ; chanPtr = chanPtr->upChanPtr) {
ChanThreadAction(chanPtr, TCL_CHANNEL_THREAD_REMOVE);
}
+
+ /* Channel is not managed by any thread */
+ statePtr->managingThread = NULL;
}
/*
@@ -8390,6 +8396,13 @@ Tcl_NotifyChannel(
Tcl_Preserve(statePtr);
/*
+ * Avoid processing if the channel owner has been changed.
+ */
+ if (statePtr->managingThread != Tcl_GetCurrentThread()) {
+ goto done;
+ }
+
+ /*
* If we are flushing in the background, be sure to call FlushChannel for
* writable events. Note that we have to discard the writable event so we
* don't call any write handlers before the flush is complete.
@@ -8423,6 +8436,13 @@ Tcl_NotifyChannel(
} else {
chPtr = chPtr->nextPtr;
}
+
+ /*
+ * Stop if the channel owner has been changed in-between.
+ */
+ if (chanPtr->state->managingThread != Tcl_GetCurrentThread()) {
+ goto done;
+ }
}
/*
@@ -8440,6 +8460,7 @@ Tcl_NotifyChannel(
UpdateInterest(chanPtr);
}
+done:
Tcl_Release(statePtr);
TclChannelRelease(channel);
@@ -8939,6 +8960,11 @@ TclChannelEventScriptInvoker(
int result; /* Result of call to eval script. */
/*
+ * Be sure event executed in managed channel (covering bugs similar [f583715154]).
+ */
+ assert(chanPtr->state->managingThread == Tcl_GetCurrentThread());
+
+ /*
* We must preserve the interpreter so we can report errors on it later.
* Note that we do not need to preserve the channel because that is done
* by Tcl_NotifyChannel before calling channel handlers.