diff options
author | pooryorick <com.digitalsmarties@pooryorick.com> | 2019-05-01 10:44:55 (GMT) |
---|---|---|
committer | pooryorick <com.digitalsmarties@pooryorick.com> | 2019-05-01 10:44:55 (GMT) |
commit | f50dfbd5042937c16e1ff5ce90e7bc73e5bd5d88 (patch) | |
tree | 4e3675edee67c09fa565997d081f8288d1f3f6ee /generic | |
parent | b21bc1e84f40c6e09c7d3fc3766a4106eab719d8 (diff) | |
parent | 89c677d626e30f3439e20b018fc86d1f5f0c3246 (diff) | |
download | tcl-f50dfbd5042937c16e1ff5ce90e7bc73e5bd5d88.zip tcl-f50dfbd5042937c16e1ff5ce90e7bc73e5bd5d88.tar.gz tcl-f50dfbd5042937c16e1ff5ce90e7bc73e5bd5d88.tar.bz2 |
merge bug-de232b49f2
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclIO.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index cf91307..118820a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3463,6 +3463,11 @@ Tcl_Close( Tcl_ClearChannelHandlers(chan); /* + * Cancel any outstanding timer. + */ + Tcl_DeleteTimerHandler(statePtr->timer); + + /* * Invoke the registered close callbacks and delete their records. */ @@ -4447,6 +4452,8 @@ Write( } } + UpdateInterest(chanPtr); + return total; } @@ -8475,9 +8482,9 @@ UpdateInterest( * * - Tcl drops READABLE here, because it has data in its own * buffers waiting to be read by the extension. - * - A READABLE event is syntesized via timer. + * - A READABLE event is synthesized via timer. * - The OS still reports the EXCEPTION condition on the file. - * - And the extension gets the EXCPTION event first, and handles + * - And the extension gets the EXCEPTION event first, and handles * this as EOF. * * End result ==> Premature end of reading from a file. @@ -8503,6 +8510,16 @@ UpdateInterest( } } } + + if (!statePtr->timer + && mask & TCL_WRITABLE + && GotFlag(statePtr, CHANNEL_NONBLOCKING)) { + + statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, + ChannelTimerProc,chanPtr); + } + + ChanWatch(chanPtr, mask); } @@ -8531,6 +8548,21 @@ ChannelTimerProc( ChannelState *statePtr = chanPtr->state; /* State info for channel */ + Tcl_Preserve(statePtr); + statePtr->timer = NULL; + if (statePtr->interestMask & TCL_WRITABLE + && GotFlag(statePtr, CHANNEL_NONBLOCKING) + && !GotFlag(statePtr, BG_FLUSH_SCHEDULED) + ) { + /* + * Restart the timer in case a channel handler reenters the event loop + * before UpdateInterest gets called by Tcl_NotifyChannel. + */ + statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, + ChannelTimerProc,chanPtr); + Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_WRITABLE); + } + if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) && (statePtr->interestMask & TCL_READABLE) && (statePtr->inQueueHead != NULL) @@ -8542,13 +8574,11 @@ ChannelTimerProc( statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); - Tcl_Preserve(statePtr); Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE); - Tcl_Release(statePtr); } else { - statePtr->timer = NULL; UpdateInterest(chanPtr); } + Tcl_Release(statePtr); } /* |