summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsebres <sebres@users.sourceforge.net>2024-05-17 12:57:46 (GMT)
committersebres <sebres@users.sourceforge.net>2024-05-17 12:57:46 (GMT)
commitc61a5211fee9d7e1e8c6a94f2e7e50d9a5c1f22e (patch)
treec64acb23db56140905c09335807ec11efbf8be48
parent5f1e4ec2fdb8c09c4e6075e6d324b7fefb5bfcc3 (diff)
parent75db8f1ef9e26fc0c83dc13816f3dc12502c82b2 (diff)
downloadtcl-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.c30
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;
}