diff options
author | dgp <dgp@users.sourceforge.net> | 2020-04-01 11:54:27 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2020-04-01 11:54:27 (GMT) |
commit | 14c6f5491be3cd441df1f7142510835c67f78e9d (patch) | |
tree | 2154042e4fc5ed59be9173811bb3f8a0803d8d40 /generic | |
parent | f8ae8cc375adc04ed8d810255e0d282cce9ae35e (diff) | |
parent | f394d8c0d4ef97cd0aebf1ce7de1ecb86a50ba9d (diff) | |
download | tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.zip tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.gz tcl-14c6f5491be3cd441df1f7142510835c67f78e9d.tar.bz2 |
merge 8.6
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclIO.c | 26 |
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. |