diff options
| author | sebres <sebres@users.sourceforge.net> | 2024-05-17 12:57:46 (GMT) |
|---|---|---|
| committer | sebres <sebres@users.sourceforge.net> | 2024-05-17 12:57:46 (GMT) |
| commit | c61a5211fee9d7e1e8c6a94f2e7e50d9a5c1f22e (patch) | |
| tree | c64acb23db56140905c09335807ec11efbf8be48 | |
| parent | 5f1e4ec2fdb8c09c4e6075e6d324b7fefb5bfcc3 (diff) | |
| parent | 75db8f1ef9e26fc0c83dc13816f3dc12502c82b2 (diff) | |
| download | tcl-c61a5211fee9d7e1e8c6a94f2e7e50d9a5c1f22e.zip tcl-c61a5211fee9d7e1e8c6a94f2e7e50d9a5c1f22e.tar.gz tcl-c61a5211fee9d7e1e8c6a94f2e7e50d9a5c1f22e.tar.bz2 | |
merge apn-channelstate-leak, fixes possible leaks on several members that may be set after the close, asynchronously or via some callbacks or handlers
| -rw-r--r-- | generic/tclIO.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index c3844af..165a07e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2949,6 +2949,34 @@ FlushChannel( return errorCode; } +static void +FreeChannelState( + char *blockPtr) /* Channel state to free. */ +{ + ChannelState *statePtr = (ChannelState *)blockPtr; + /* + * Even after close some members can be filled again (in events etc). + * Test in bug [79474c588] illustrates one leak (on remaining chanMsg). + * Possible other fields need freeing on some constellations. + */ + + DiscardInputQueued(statePtr, 1); + if (statePtr->curOutPtr != NULL) { + ReleaseChannelBuffer(statePtr->curOutPtr); + } + DiscardOutputQueued(statePtr); + + DeleteTimerHandler(statePtr); + + if (statePtr->chanMsg) { + Tcl_DecrRefCount(statePtr->chanMsg); + } + if (statePtr->unreportedMsg) { + Tcl_DecrRefCount(statePtr->unreportedMsg); + } + ckfree(statePtr); +} + /* *---------------------------------------------------------------------- * @@ -3125,7 +3153,7 @@ CloseChannel( ChannelFree(chanPtr); - Tcl_EventuallyFree(statePtr, TCL_DYNAMIC); + Tcl_EventuallyFree(statePtr, FreeChannelState); return errorCode; } |
