diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-04-18 15:32:16 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-04-18 15:32:16 (GMT) |
| commit | f7b4c00c2817d11f545b2bbf7ee60e6567ab169c (patch) | |
| tree | 573f149c24b58c211466c72770d8b214e324dd70 /generic/tclIO.c | |
| parent | e3caaff1547bb50b7e0b41f1aaf596f379906b34 (diff) | |
| download | tcl-f7b4c00c2817d11f545b2bbf7ee60e6567ab169c.zip tcl-f7b4c00c2817d11f545b2bbf7ee60e6567ab169c.tar.gz tcl-f7b4c00c2817d11f545b2bbf7ee60e6567ab169c.tar.bz2 | |
Fix [18f4a94d03] by backing out [9bcec7cd880540c3] (again)
Diffstat (limited to 'generic/tclIO.c')
| -rw-r--r-- | generic/tclIO.c | 87 |
1 files changed, 19 insertions, 68 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 0d8d4db..92b8b62 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -167,7 +167,6 @@ static int CheckForDeadChannel(Tcl_Interp *interp, static void CheckForStdChannelsBeingClosed(Tcl_Channel chan); static void CleanupChannelHandlers(Tcl_Interp *interp, Channel *chanPtr); -static void CleanupTimerHandler(ChannelState *statePtr); static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr, int errorCode); static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, @@ -3194,8 +3193,8 @@ CloseChannel( /* * Cancel any outstanding timer. */ - DeleteTimerHandler(statePtr); + DeleteTimerHandler(statePtr); /* * Mark the channel as deleted by clearing the type structure. @@ -3545,11 +3544,6 @@ Tcl_Close( Tcl_ClearChannelHandlers(chan); /* - * Cancel any outstanding timer. - */ - DeleteTimerHandler(statePtr); - - /* * Invoke the registered close callbacks and delete their records. */ @@ -7626,7 +7620,6 @@ Tcl_Eof( return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0; } - /* *---------------------------------------------------------------------- * @@ -7652,7 +7645,7 @@ TclChannelGetBlockingMode( return GotFlag(statePtr, CHANNEL_NONBLOCKING) ? 0 : 1; } - + /* *---------------------------------------------------------------------- * @@ -8760,7 +8753,6 @@ UpdateInterest( { ChannelState *statePtr = chanPtr->state; /* State info for channel */ - ChannelBuffer *bufPtr = statePtr->outQueueHead; int mask = statePtr->interestMask; if (chanPtr->typePtr == NULL) { @@ -8838,20 +8830,6 @@ UpdateInterest( } } } - - if (!statePtr->timer - && (mask & TCL_WRITABLE) - && GotFlag(statePtr, CHANNEL_NONBLOCKING) - && bufPtr - && !IsBufferEmpty(bufPtr) - && !IsBufferFull(bufPtr) - ) { - TclChannelPreserve((Tcl_Channel)chanPtr); - statePtr->timerChanPtr = chanPtr; - statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, - ChannelTimerProc,chanPtr); - } - ChanWatch(chanPtr, mask); } @@ -8880,51 +8858,30 @@ ChannelTimerProc( /* State info for channel */ ChannelState *statePtr = chanPtr->state; - /* TclChannelPreserve() must be called before the current function was - * scheduled, is already in effect. In this function it guards against - * deallocation in Tcl_NotifyChannel and also keps the channel preserved - * until ChannelTimerProc is later called again. - */ - if (chanPtr->typePtr == NULL) { - CleanupTimerHandler(statePtr); - } else { - Tcl_Preserve(statePtr); statePtr->timer = NULL; - if (statePtr->interestMask & TCL_WRITABLE - && GotFlag(statePtr, CHANNEL_NONBLOCKING) - && !GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { + TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr); + statePtr->timerChanPtr = NULL; + } else { + if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) + && (statePtr->interestMask & TCL_READABLE) + && (statePtr->inQueueHead != NULL) + && IsBufferReady(statePtr->inQueueHead)) { /* * 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); + Tcl_Preserve(statePtr); + Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE); + Tcl_Release(statePtr); } else { - /* The channel may have just been closed from within Tcl_NotifyChannel */ - if (!GotFlag(statePtr, CHANNEL_INCLOSE)) { - if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) - && (statePtr->interestMask & TCL_READABLE) - && (statePtr->inQueueHead != NULL) - && IsBufferReady(statePtr->inQueueHead)) { - /* - * 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_READABLE); - } else { - CleanupTimerHandler(statePtr); - UpdateInterest(chanPtr); - } - } else { - CleanupTimerHandler(statePtr); - } + statePtr->timer = NULL; + UpdateInterest(chanPtr); + TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr); + statePtr->timerChanPtr = NULL; } - Tcl_Release(statePtr); } } @@ -8935,17 +8892,11 @@ DeleteTimerHandler( { if (statePtr->timer != NULL) { Tcl_DeleteTimerHandler(statePtr->timer); - CleanupTimerHandler(statePtr); + statePtr->timer = NULL; + TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr); + statePtr->timerChanPtr = NULL; } } -static void -CleanupTimerHandler( - ChannelState *statePtr -){ - TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr); - statePtr->timer = NULL; - statePtr->timerChanPtr = NULL; -} /* *---------------------------------------------------------------------- |
