From 228272365c7aec6154a3468e75f99981152c7a3c Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 May 2014 03:30:55 +0000 Subject: Stop leaks of cloned Tcl_ChannelTypes. --- generic/tclIORChan.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 17c1593..7630473 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1019,6 +1019,7 @@ ReflectClose( Tcl_Obj *resObj; /* Result data for 'close' */ ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ Tcl_HashEntry* hPtr; /* Entry in the above map */ + Tcl_ChannelType *tctPtr; if (TclInThreadExit()) { /* @@ -1055,6 +1056,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return EOK; } @@ -1118,6 +1124,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); #ifdef TCL_THREADS } @@ -2033,13 +2044,6 @@ FreeReflectedChannel( { Channel *chanPtr = (Channel *) rcPtr->chan; - if (chanPtr->typePtr != &tclRChannelType) { - /* - * Delete a cloned ChannelType structure. - */ - - ckfree((char*) chanPtr->typePtr); - } Tcl_Release(chanPtr); Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); @@ -2698,11 +2702,13 @@ ForwardProc( * call upon for the driver. */ - case ForwardedClose: + case ForwardedClose: { /* * No parameters/results. */ + Tcl_ChannelType *tctPtr; + if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) { ForwardSetObjError(paramPtr, resObj); } @@ -2727,8 +2733,14 @@ ForwardProc( Tcl_GetChannelName (rcPtr->chan)); Tcl_DeleteHashEntry (hPtr); + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); break; + } case ForwardedInput: { Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead); -- cgit v0.12