Tcl Source Code

Check-in [d699b9b145]
Login

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

Overview
Comment:Fix for [a12ad5c4bd7efcf2], buffer allocation on every call to Write().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-branch
Files: files | file ages | folders
SHA3-256: d699b9b1453b67348fbfb689dad7c1e5c0676e9e88d24d1b69ff0d9773297324
User & Date: pooryorick 2022-04-20 12:08:45
References
2022-04-20
12:10 Ticket [a12ad5c4bd] buffer allocation on every call to Write in tclIO.c status still Open with 3 other changes artifact: 58bbeecb6b user: pooryorick
Context
2022-04-20
14:34
one more boolPtr -> intPtr check-in: 352215a109 user: jan.nijtmans tags: core-8-branch
14:08
Merge 8.7 check-in: c4c36b2706 user: jan.nijtmans tags: tip-618
12:50
Merge 8.7 check-in: bd0ef87d4d user: jan.nijtmans tags: trunk, main
12:08
Fix for [a12ad5c4bd7efcf2], buffer allocation on every call to Write(). check-in: d699b9b145 user: pooryorick tags: core-8-branch
11:27
Fix bf0f4808d7: macOS Aqua : CFLAGS_OPTIMIZE check-in: 28b1e88eef user: jan.nijtmans tags: core-8-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclIO.c.

2707
2708
2709
2710
2711
2712
2713

2714
2715
2716
2717
2718
2719
2720
    int written;		/* Amount of output data actually written in
				 * current round. */
    int errorCode = 0;		/* Stores POSIX error codes from channel
				 * driver operations. */
    int wroteSome = 0;		/* Set to one if any data was written to the
				 * driver. */


    /*
     * Prevent writing on a dead channel -- a channel that has been closed but
     * not yet deallocated. This can occur if the exit handler for the channel
     * deallocation runs before all channels are deregistered in all
     * interpreters.
     */








>







2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
    int written;		/* Amount of output data actually written in
				 * current round. */
    int errorCode = 0;		/* Stores POSIX error codes from channel
				 * driver operations. */
    int wroteSome = 0;		/* Set to one if any data was written to the
				 * driver. */

    int bufExists;
    /*
     * Prevent writing on a dead channel -- a channel that has been closed but
     * not yet deallocated. This can occur if the exit handler for the channel
     * deallocation runs before all channels are deregistered in all
     * interpreters.
     */

2875
2876
2877
2878
2879
2880
2881
2882
2883

2884
2885
2886
2887
2888
2889
2890
2891
2892
2893











2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906

2907
2908
2909
2910
2911
2912
2913
2914
	    }

	    /*
	     * When we get an error we throw away all the output currently
	     * queued.
	     */

	    DiscardOutputQueued(statePtr);
	    ReleaseChannelBuffer(bufPtr);

	    break;
	} else {
	    /*
	     * TODO: Consider detecting and reacting to short writes on
	     * blocking channels.  Ought not happen.  See iocmd-24.2.
	     */

	    wroteSome = 1;
	}












	bufPtr->nextRemoved += written;

	/*
	 * If this buffer is now empty, recycle it.
	 */

	if (IsBufferEmpty(bufPtr)) {
	    statePtr->outQueueHead = bufPtr->nextPtr;
	    if (statePtr->outQueueHead == NULL) {
		statePtr->outQueueTail = NULL;
	    }
	    RecycleBuffer(statePtr, bufPtr, 0);
	}

	ReleaseChannelBuffer(bufPtr);
    }	/* Closes "while". */

    /*
     * If we wrote some data while flushing in the background, we are done.
     * We can't finish the background flush until we run out of data and the
     * channel becomes writable again. This ensures that all of the pending
     * data has been flushed at the system level.







<

>










>
>
>
>
>
>
>
>
>
>
>
|

|
|
|

|
|
|
|
|
|
|
>
|







2876
2877
2878
2879
2880
2881
2882

2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
	    }

	    /*
	     * When we get an error we throw away all the output currently
	     * queued.
	     */


	    ReleaseChannelBuffer(bufPtr);
	    DiscardOutputQueued(statePtr);
	    break;
	} else {
	    /*
	     * TODO: Consider detecting and reacting to short writes on
	     * blocking channels.  Ought not happen.  See iocmd-24.2.
	     */

	    wroteSome = 1;
	}

	bufExists = bufPtr->refCount > 1;
	ReleaseChannelBuffer(bufPtr);
	if (bufExists) {
	    /* There is still a reference to this buffer other than the one
	     * this routine just released, meaning that final cleanup of the
	     * buffer hasn't been ordered by, e.g. by a reflected channel
	     * closing the channel from within one of its handler scripts (not
	     * something one would expecte, but it must be considered).  Normal
	     * operations on the buffer can proceed.
	     */

	    bufPtr->nextRemoved += written;

	    /*
	     * If this buffer is now empty, recycle it.
	     */

	    if (IsBufferEmpty(bufPtr)) {
		statePtr->outQueueHead = bufPtr->nextPtr;
		if (statePtr->outQueueHead == NULL) {
		    statePtr->outQueueTail = NULL;
		}
		RecycleBuffer(statePtr, bufPtr, 0);
	    }
	}

    }	/* Closes "while". */

    /*
     * If we wrote some data while flushing in the background, we are done.
     * We can't finish the background flush until we run out of data and the
     * channel becomes writable again. This ensures that all of the pending
     * data has been flushed at the system level.
6953
6954
6955
6956
6957
6958
6959

6960
6961
6962
6963
6964

6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
	statePtr->inQueueTail = bufPtr;
    } else {
	toRead = SpaceLeft(bufPtr);
    }

    PreserveChannelBuffer(bufPtr);
    nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead);


    if (nread < 0) {
	result = Tcl_GetErrno();
    } else {
	result = 0;

	bufPtr->nextAdded += nread;
    }

    ReleaseChannelBuffer(bufPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Seek --







>





>
|
|
|
|







6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
	statePtr->inQueueTail = bufPtr;
    } else {
	toRead = SpaceLeft(bufPtr);
    }

    PreserveChannelBuffer(bufPtr);
    nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead);
    ReleaseChannelBuffer(bufPtr);

    if (nread < 0) {
	result = Tcl_GetErrno();
    } else {
	result = 0;
	if (statePtr->inQueueTail != NULL) {
	    statePtr->inQueueTail->nextAdded += nread;
	}
    }

    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_Seek --