summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authorpooryorick <com.digitalsmarties@pooryorick.com>2023-03-13 19:07:25 (GMT)
committerpooryorick <com.digitalsmarties@pooryorick.com>2023-03-13 19:07:25 (GMT)
commit5094fb7825d5dfba740b8feee59c6b87233da4aa (patch)
tree2a7d5e57a594170c14de4904dcb39cc4c837c6f2 /generic
parent6d7423228211f312016f0c62ce1bc86c3d3777db (diff)
parent967e55306e7bb0a58a7cf2c5b905a2608f395875 (diff)
downloadtcl-5094fb7825d5dfba740b8feee59c6b87233da4aa.zip
tcl-5094fb7825d5dfba740b8feee59c6b87233da4aa.tar.gz
tcl-5094fb7825d5dfba740b8feee59c6b87233da4aa.tar.bz2
Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on
TCP client socket.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 85ff39b..715f8c7 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -8551,6 +8551,7 @@ UpdateInterest(
mask &= ~TCL_EXCEPTION;
if (!statePtr->timer) {
+ TclChannelPreserve((Tcl_Channel)chanPtr);
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc, chanPtr);
}
@@ -8584,23 +8585,28 @@ ChannelTimerProc(
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
- 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_Preserve(statePtr);
- Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
- Tcl_Release(statePtr);
+ if (chanPtr->typePtr == NULL) {
+ TclChannelRelease((Tcl_Channel)chanPtr);
} else {
- statePtr->timer = NULL;
- UpdateInterest(chanPtr);
+ 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_Preserve(statePtr);
+ Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
+ Tcl_Release(statePtr);
+ } else {
+ statePtr->timer = NULL;
+ UpdateInterest(chanPtr);
+ TclChannelRelease((Tcl_Channel)chanPtr);
+ }
}
}