diff options
author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-03-16 17:29:12 (GMT) |
---|---|---|
committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-03-16 17:29:12 (GMT) |
commit | 5655318f50b3bc51f8cba32759e01ae8c7694cc9 (patch) | |
tree | 00a3c065ecacd8eaed206f6dda391d4e9c82c54b /generic | |
parent | a3c59e320df775f0d6849e5d3163292280b3b386 (diff) | |
parent | ae0471127efb9e3be2f45c25f91ba07f6a09eae5 (diff) | |
download | tcl-5655318f50b3bc51f8cba32759e01ae8c7694cc9.zip tcl-5655318f50b3bc51f8cba32759e01ae8c7694cc9.tar.gz tcl-5655318f50b3bc51f8cba32759e01ae8c7694cc9.tar.bz2 |
Merge 8.7
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tcl.h | 7 | ||||
-rw-r--r-- | generic/tclIO.c | 52 | ||||
-rw-r--r-- | generic/tclIO.h | 3 | ||||
-rw-r--r-- | generic/tclTest.c | 4 |
4 files changed, 48 insertions, 18 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index a92680d..705ec3a 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2427,10 +2427,17 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp, #endif #ifdef USE_TCL_STUBS +# if TCL_UTF_MAX < 4 # define Tcl_InitStubs(interp, version, exact) \ (Tcl_InitStubs)(interp, version, \ (exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \ TCL_STUB_MAGIC) +# else +# define Tcl_InitStubs(interp, version, exact) \ + (Tcl_InitStubs)(interp, TCL_PATCH_LEVEL, \ + 1|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \ + TCL_STUB_MAGIC) +# endif #else # define Tcl_InitStubs(interp, version, exact) \ Tcl_PkgInitStubsCheck(interp, version, \ diff --git a/generic/tclIO.c b/generic/tclIO.c index dbdbda5..3f7fe86 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -165,6 +165,7 @@ 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, @@ -172,6 +173,7 @@ static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static int CopyData(CopyState *csPtr, int mask); +static void DeleteTimerHandler(ChannelState *statePtr); static int MoveBytes(CopyState *csPtr); static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj); @@ -1734,6 +1736,7 @@ Tcl_CreateChannel( statePtr->scriptRecordPtr = NULL; statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE; statePtr->timer = NULL; + statePtr->timerChanPtr = NULL; statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; statePtr->outputStage = NULL; @@ -3191,8 +3194,8 @@ CloseChannel( /* * Cancel any outstanding timer. */ + DeleteTimerHandler(statePtr); - Tcl_DeleteTimerHandler(statePtr->timer); /* * Mark the channel as deleted by clearing the type structure. @@ -3544,7 +3547,7 @@ Tcl_Close( /* * Cancel any outstanding timer. */ - Tcl_DeleteTimerHandler(statePtr->timer); + DeleteTimerHandler(statePtr); /* * Invoke the registered close callbacks and delete their records. @@ -4019,8 +4022,7 @@ Tcl_ClearChannelHandlers( /* * Cancel any outstanding timer. */ - - Tcl_DeleteTimerHandler(statePtr->timer); + DeleteTimerHandler(statePtr); /* * Remove any references to channel handlers for this channel that may be @@ -8715,8 +8717,9 @@ UpdateInterest( if (!statePtr->timer) { TclChannelPreserve((Tcl_Channel)chanPtr); + statePtr->timerChanPtr = chanPtr; statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, - ChannelTimerProc, chanPtr); + ChannelTimerProc, chanPtr); } } } @@ -8726,6 +8729,7 @@ UpdateInterest( && GotFlag(statePtr, CHANNEL_NONBLOCKING)) { TclChannelPreserve((Tcl_Channel)chanPtr); + statePtr->timerChanPtr = chanPtr; statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, ChannelTimerProc,chanPtr); } @@ -8756,7 +8760,6 @@ ChannelTimerProc( void *clientData) { Channel *chanPtr = (Channel *)clientData; - /* State info for channel */ ChannelState *statePtr = chanPtr->state; @@ -8767,7 +8770,7 @@ ChannelTimerProc( */ if (chanPtr->typePtr == NULL) { - TclChannelRelease((Tcl_Channel)chanPtr); + CleanupTimerHandler(statePtr); } else { Tcl_Preserve(statePtr); statePtr->timer = NULL; @@ -8780,35 +8783,52 @@ ChannelTimerProc( * before UpdateInterest gets called by Tcl_NotifyChannel. */ statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME, - ChannelTimerProc,chanPtr); + ChannelTimerProc,chanPtr); Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_WRITABLE); } 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)) { + && (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); + ChannelTimerProc,chanPtr); Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE); } else { - TclChannelRelease((Tcl_Channel)chanPtr); + CleanupTimerHandler(statePtr); UpdateInterest(chanPtr); } } else { - TclChannelRelease((Tcl_Channel)chanPtr); + CleanupTimerHandler(statePtr); } } - Tcl_Release(statePtr); } - +} + +static void +DeleteTimerHandler( + ChannelState *statePtr +) +{ + if (statePtr->timer != NULL) { + Tcl_DeleteTimerHandler(statePtr->timer); + CleanupTimerHandler(statePtr); + } +} +static void +CleanupTimerHandler( + ChannelState *statePtr +){ + TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr); + statePtr->timer = NULL; + statePtr->timerChanPtr = NULL; } /* diff --git a/generic/tclIO.h b/generic/tclIO.h index 2500fa3..109c770 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -188,6 +188,9 @@ typedef struct ChannelState { * handlers ("fileevent") on this channel. */ Tcl_Size bufSize; /* What size buffers to allocate? */ Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */ + Channel *timerChanPtr; /* Needed in order to decrement the refCount of + the right channel when the timer is + deleted. */ struct CopyState *csPtrR; /* State of background copy for which channel * is input, or NULL. */ struct CopyState *csPtrW; /* State of background copy for which channel diff --git a/generic/tclTest.c b/generic/tclTest.c index 522e6f8..f68029a 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -2122,7 +2122,7 @@ static int UtfExtWrapper( /* Assumes state is integer if not "" */ Tcl_WideInt wide; if (Tcl_GetWideIntFromObj(interp, objv[5], &wide) == TCL_OK) { - encState = (Tcl_EncodingState) wide; + encState = (Tcl_EncodingState)(size_t)wide; encStatePtr = &encState; } else if (Tcl_GetCharLength(objv[5]) == 0) { encStatePtr = NULL; @@ -2210,7 +2210,7 @@ static int UtfExtWrapper( } result = TCL_OK; resultObjs[1] = - encStatePtr ? Tcl_NewWideIntObj((Tcl_WideInt)encState) : Tcl_NewObj(); + encStatePtr ? Tcl_NewWideIntObj((Tcl_WideInt)(size_t)encState) : Tcl_NewObj(); resultObjs[2] = Tcl_NewByteArrayObj(bufPtr, dstLen); if (srcReadVar) { if (Tcl_ObjSetVar2(interp, |