Tcl Source Code

Check-in [450a131ee7]
Login

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

Overview
Comment:Likely fix for channel mem leaks.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | core-8-6-3 | release | core-8-6-3-rc
Files: files | file ages | folders
SHA1: 450a131ee70336913b3ec1fd0e80f6e9efd0d78c
User & Date: dgp 2014-11-11 22:23:57.678
Context
2016-09-08
12:36
merge 8.6.3 check-in: 5e598c8a3e user: dgp tags: dgp-literal-reform
2015-02-05
19:23
Backport of channel mem leak fix that got missed before. check-in: 9682f2723c user: dgp tags: core-8-5-branch
2014-11-17
20:55
merge 8.6.3 core (ref: [core-8-6-3]; nb: specific tag could change in future.) check-in: 5c0a5f44ce user: bch tags: bch_coverity
2014-11-12
04:35
merge release check-in: 2b53ef7858 user: dgp tags: trunk
2014-11-11
22:23
Likely fix for channel mem leaks. Closed-Leaf check-in: 450a131ee7 user: dgp tags: core-8-6-3, release, core-8-6-3-rc
2014-11-07
17:48
Correct -singleproc 1 testing flaws. check-in: b71c2af14a user: dgp tags: rc2, core-8-6-3-rc
Changes
Unified Diff Ignore Whitespace Patch
Changes to generic/tclIO.c.
151
152
153
154
155
156
157

158
159
160
161
162
163
164
 * Static functions in this file:
 */

static ChannelBuffer *	AllocChannelBuffer(int length);
static void		PreserveChannelBuffer(ChannelBuffer *bufPtr);
static void		ReleaseChannelBuffer(ChannelBuffer *bufPtr);
static int		IsShared(ChannelBuffer *bufPtr);

static void		ChannelTimerProc(ClientData clientData);
static int		ChanRead(Channel *chanPtr, char *dst, int dstSize);
static int		CheckChannelErrors(ChannelState *statePtr,
			    int direction);
static int		CheckForDeadChannel(Tcl_Interp *interp,
			    ChannelState *statePtr);
static void		CheckForStdChannelsBeingClosed(Tcl_Channel chan);







>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
 * Static functions in this file:
 */

static ChannelBuffer *	AllocChannelBuffer(int length);
static void		PreserveChannelBuffer(ChannelBuffer *bufPtr);
static void		ReleaseChannelBuffer(ChannelBuffer *bufPtr);
static int		IsShared(ChannelBuffer *bufPtr);
static void		ChannelFree(Channel *chanPtr);
static void		ChannelTimerProc(ClientData clientData);
static int		ChanRead(Channel *chanPtr, char *dst, int dstSize);
static int		CheckChannelErrors(ChannelState *statePtr,
			    int direction);
static int		CheckForDeadChannel(Tcl_Interp *interp,
			    ChannelState *statePtr);
static void		CheckForStdChannelsBeingClosed(Tcl_Channel chan);
1910
1911
1912
1913
1914
1915
1916










1917
1918
1919
1920
1921
1922
1923
	return;
    }
    if (chanPtr->typePtr == NULL) {
	ckfree(chanPtr);
    }
}












/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnstackChannel --
 *
 *	Unstacks an entry in the hash table for a Tcl_Channel record. This is







>
>
>
>
>
>
>
>
>
>







1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
	return;
    }
    if (chanPtr->typePtr == NULL) {
	ckfree(chanPtr);
    }
}

static void
ChannelFree(
    Channel *chanPtr)
{
    if (chanPtr->refCount == 0) {
	ckfree(chanPtr);
	return;
    }
    chanPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_UnstackChannel --
 *
 *	Unstacks an entry in the hash table for a Tcl_Channel record. This is
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
	 */

	/*
	 * Close and free the channel driver state.
	 */

	result = ChanClose(chanPtr, interp);
	chanPtr->typePtr = NULL;

	UpdateInterest(statePtr->topChanPtr);

	if (result != 0) {
	    Tcl_SetErrno(result);

	    /*







|







2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
	 */

	/*
	 * Close and free the channel driver state.
	 */

	result = ChanClose(chanPtr, interp);
	ChannelFree(chanPtr);

	UpdateInterest(statePtr->topChanPtr);

	if (result != 0) {
	    Tcl_SetErrno(result);

	    /*
3014
3015
3016
3017
3018
3019
3020
3021

3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
	Channel *downChanPtr = chanPtr->downChanPtr;

	statePtr->nextCSPtr = tsdPtr->firstCSPtr;
	tsdPtr->firstCSPtr = statePtr;

	statePtr->topChanPtr = downChanPtr;
	downChanPtr->upChanPtr = NULL;
	chanPtr->typePtr = NULL;


	return Tcl_Close(interp, (Tcl_Channel) downChanPtr);
    }

    /*
     * There is only the TOP Channel, so we free the remaining pointers we
     * have and then ourselves. Since this is the last of the channels in the
     * stack, make sure to free the ChannelState structure associated with it.
     */

    chanPtr->typePtr = NULL;

    Tcl_EventuallyFree(statePtr, TCL_DYNAMIC);

    return errorCode;
}

/*







|
>










|







3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
	Channel *downChanPtr = chanPtr->downChanPtr;

	statePtr->nextCSPtr = tsdPtr->firstCSPtr;
	tsdPtr->firstCSPtr = statePtr;

	statePtr->topChanPtr = downChanPtr;
	downChanPtr->upChanPtr = NULL;

	ChannelFree(chanPtr);

	return Tcl_Close(interp, (Tcl_Channel) downChanPtr);
    }

    /*
     * There is only the TOP Channel, so we free the remaining pointers we
     * have and then ourselves. Since this is the last of the channels in the
     * stack, make sure to free the ChannelState structure associated with it.
     */

    ChannelFree(chanPtr);

    Tcl_EventuallyFree(statePtr, TCL_DYNAMIC);

    return errorCode;
}

/*