Tcl Source Code

Check-in [a719a1392c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-6-branch
Files: files | file ages | folders
SHA3-256: a719a1392ca5035997c9456cd9b129a0630cfd46212e944e18dadf4b3751cd75
User & Date: pooryorick 2023-03-14 20:30:34
References
2023-03-15
11:43 Ticket [ea69b0258a] Crash when using a channel transformation on TCP client socket status still Pending with 3 other changes artifact: 5e9fa93a3d user: pooryorick
Context
2023-03-15
12:53
Misspelled constraint created testing noise. check-in: f45aa5083a user: dgp tags: core-8-6-branch
09:32
Merge-mark. @nathan, please do forward merges from core-8-6-branch -> core-8-branch -> trunk. Fossil... check-in: 167eb8706f user: jan.nijtmans tags: core-8-branch
2023-03-14
20:30
Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client so... check-in: a719a1392c user: pooryorick tags: core-8-6-branch
20:27
Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client so... Closed-Leaf check-in: 8aee50448c user: pooryorick tags: bug-ea69b0258a9833cb6
10:05
Add "ucs-2" constraint to encoding-bug-183a1adcc0-5 testcase, otherwise it fails with TCL_UTF_MAX>3.... check-in: 7609a40b91 user: jan.nijtmans tags: core-8-6-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclIO.c.

1695
1696
1697
1698
1699
1700
1701

1702
1703
1704
1705
1706
1707
1708
    statePtr->inQueueHead	= NULL;
    statePtr->inQueueTail	= NULL;
    statePtr->chPtr		= NULL;
    statePtr->interestMask	= 0;
    statePtr->scriptRecordPtr	= NULL;
    statePtr->bufSize		= CHANNELBUFFER_DEFAULT_SIZE;
    statePtr->timer		= NULL;

    statePtr->csPtrR		= NULL;
    statePtr->csPtrW		= NULL;
    statePtr->outputStage	= NULL;

    /*
     * As we are creating the channel, it is obviously the top for now.
     */







>







1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
    statePtr->inQueueHead	= NULL;
    statePtr->inQueueTail	= NULL;
    statePtr->chPtr		= NULL;
    statePtr->interestMask	= 0;
    statePtr->scriptRecordPtr	= NULL;
    statePtr->bufSize		= CHANNELBUFFER_DEFAULT_SIZE;
    statePtr->timer		= NULL;
    statePtr->timerChanPtr	= NULL;
    statePtr->csPtrR		= NULL;
    statePtr->csPtrW		= NULL;
    statePtr->outputStage	= NULL;

    /*
     * As we are creating the channel, it is obviously the top for now.
     */
3089
3090
3091
3092
3093
3094
3095

3096





3097
3098
3099
3100
3101
3102
3103
	}
    }

    /*
     * Cancel any outstanding timer.
     */


    Tcl_DeleteTimerHandler(statePtr->timer);






    /*
     * Mark the channel as deleted by clearing the type structure.
     */

    if (chanPtr->downChanPtr != NULL) {
	Channel *downChanPtr = chanPtr->downChanPtr;







>
|
>
>
>
>
>







3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
	}
    }

    /*
     * Cancel any outstanding timer.
     */

    if (statePtr->timer != NULL) {
	Tcl_DeleteTimerHandler(statePtr->timer);
	statePtr->timer = NULL;
	TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr);
	statePtr->timerChanPtr = NULL;
    }


    /*
     * Mark the channel as deleted by clearing the type structure.
     */

    if (chanPtr->downChanPtr != NULL) {
	Channel *downChanPtr = chanPtr->downChanPtr;
3908
3909
3910
3911
3912
3913
3914

3915




3916
3917
3918
3919
3920
3921
3922
    statePtr = chanPtr->state;
    chanPtr = statePtr->topChanPtr;

    /*
     * Cancel any outstanding timer.
     */


    Tcl_DeleteTimerHandler(statePtr->timer);





    /*
     * Remove any references to channel handlers for this channel that may be
     * about to be invoked.
     */

    for (nhPtr = tsdPtr->nestedHandlerPtr; nhPtr != NULL;







>
|
>
>
>
>







3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
    statePtr = chanPtr->state;
    chanPtr = statePtr->topChanPtr;

    /*
     * Cancel any outstanding timer.
     */

    if (statePtr->timer != NULL) {
	Tcl_DeleteTimerHandler(statePtr->timer);
	statePtr->timer = NULL;
	TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr);
	statePtr->timerChanPtr = NULL;
    }

    /*
     * Remove any references to channel handlers for this channel that may be
     * about to be invoked.
     */

    for (nhPtr = tsdPtr->nestedHandlerPtr; nhPtr != NULL;
8548
8549
8550
8551
8552
8553
8554

8555
8556
8557
8558
8559
8560
8561
8562
8563
	     * testsuite on all of them.
	     */

	    mask &= ~TCL_EXCEPTION;

	    if (!statePtr->timer) {
		TclChannelPreserve((Tcl_Channel)chanPtr);

		statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
                        ChannelTimerProc, chanPtr);
	    }
	}
    }
    ChanWatch(chanPtr, mask);
}

/*







>

|







8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
	     * testsuite on all of them.
	     */

	    mask &= ~TCL_EXCEPTION;

	    if (!statePtr->timer) {
		TclChannelPreserve((Tcl_Channel)chanPtr);
		statePtr->timerChanPtr = chanPtr;
		statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
		    ChannelTimerProc, chanPtr);
	    }
	}
    }
    ChanWatch(chanPtr, mask);
}

/*
8578
8579
8580
8581
8582
8583
8584
8585
8586

8587
8588

8589

8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608

8609
8610
8611
8612
8613
8614
8615
 */

static void
ChannelTimerProc(
    ClientData clientData)
{
    Channel *chanPtr = (Channel *)clientData;
    ChannelState *statePtr = chanPtr->state;
				/* State info for channel */


    if (chanPtr->typePtr == NULL) {

	TclChannelRelease((Tcl_Channel)chanPtr);

    } 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_Preserve(statePtr);
	    Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
	    Tcl_Release(statePtr);
	} else {
	    statePtr->timer = NULL;
	    UpdateInterest(chanPtr);
	    TclChannelRelease((Tcl_Channel)chanPtr);

	}
    }
}

/*
 *----------------------------------------------------------------------
 *







<
|
>


>
|
>











|






|
>







8591
8592
8593
8594
8595
8596
8597

8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
 */

static void
ChannelTimerProc(
    ClientData clientData)
{
    Channel *chanPtr = (Channel *)clientData;

    /* State info for channel */
    ChannelState *statePtr = chanPtr->state;

    if (chanPtr->typePtr == NULL) {
	statePtr->timer = NULL;
	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_Preserve(statePtr);
	    Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
	    Tcl_Release(statePtr);
	} else {
	    statePtr->timer = NULL;
	    UpdateInterest(chanPtr);
	    TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr);
	    statePtr->timerChanPtr = NULL;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tclIO.h.

184
185
186
187
188
189
190



191
192
193
194
195
196
197
    int interestMask;		/* Mask of all events this channel has
				 * handlers for. */
    EventScriptRecord *scriptRecordPtr;
				/* Chain of all scripts registered for event
				 * handlers ("fileevent") on this channel. */
    int bufSize;		/* What size buffers to allocate? */
    Tcl_TimerToken timer;	/* Handle to wakeup timer for this channel. */



    struct CopyState *csPtrR;	/* State of background copy for which channel
				 * is input, or NULL. */
    struct CopyState *csPtrW;	/* State of background copy for which channel
				 * is output, or NULL. */
    Channel *topChanPtr;	/* Refers to topmost channel in a stack. Never
				 * NULL. */
    Channel *bottomChanPtr;	/* Refers to bottommost channel in a stack.







>
>
>







184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
    int interestMask;		/* Mask of all events this channel has
				 * handlers for. */
    EventScriptRecord *scriptRecordPtr;
				/* Chain of all scripts registered for event
				 * handlers ("fileevent") on this channel. */
    int 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
				 * is output, or NULL. */
    Channel *topChanPtr;	/* Refers to topmost channel in a stack. Never
				 * NULL. */
    Channel *bottomChanPtr;	/* Refers to bottommost channel in a stack.