diff options
author | dgp <dgp@users.sourceforge.net> | 2014-05-07 03:30:55 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-05-07 03:30:55 (GMT) |
commit | 643b20e2b21c2980154dfff9a4869d5d72d4d456 (patch) | |
tree | 91322484a93b8b1a965c3c203ec059dfe8166acf | |
parent | 68f4187dd1e16b0dfdc6b4e03787028f0009efca (diff) | |
download | tcl-643b20e2b21c2980154dfff9a4869d5d72d4d456.zip tcl-643b20e2b21c2980154dfff9a4869d5d72d4d456.tar.gz tcl-643b20e2b21c2980154dfff9a4869d5d72d4d456.tar.bz2 |
Stop leaks of cloned Tcl_ChannelTypes.
-rw-r--r-- | generic/tclIORChan.c | 28 |
1 files 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); |