diff options
author | dgp <dgp@users.sourceforge.net> | 2014-05-08 03:28:56 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-05-08 03:28:56 (GMT) |
commit | 311f44633e3dab963b7705cd04ffa3a4b6c4dcce (patch) | |
tree | 691948500985fc43c2eee0e90a31e76c654c8e18 /generic | |
parent | 3f767c15a3a870d5692ae43cd6151fb86ffa2bf3 (diff) | |
parent | 5e1038193c820c5a5ae7b27886d8d3100e18ea49 (diff) | |
download | tcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.zip tcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.tar.gz tcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.tar.bz2 |
merge trunk
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tcl.h | 8 | ||||
-rw-r--r-- | generic/tclIO.c | 13 | ||||
-rw-r--r-- | generic/tclIOCmd.c | 3 | ||||
-rw-r--r-- | generic/tclIOGT.c | 15 | ||||
-rw-r--r-- | generic/tclIORChan.c | 31 |
5 files changed, 55 insertions, 15 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index b93b3ac..e557290 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2433,9 +2433,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); /* * Include platform specific public function declarations that are accessible - * via the stubs table. + * via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only + * has effect on building it as a shared library). See ticket [3010352]. */ +#if defined(BUILD_tcl) +# undef TCLAPI +# define TCLAPI MODULE_SCOPE +#endif + #include "tclPlatDecls.h" /* diff --git a/generic/tclIO.c b/generic/tclIO.c index d5d4086..c4d9171 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2312,6 +2312,9 @@ static void PreserveChannelBuffer( ChannelBuffer *bufPtr) { + if (bufPtr->refCount == 0) { + Tcl_Panic("Reuse of ChannelBuffer!"); + } bufPtr->refCount++; } @@ -2610,6 +2613,7 @@ FlushChannel( if (errorCode == EINTR) { errorCode = 0; + ReleaseChannelBuffer(bufPtr); continue; } @@ -2631,6 +2635,7 @@ FlushChannel( UpdateInterest(chanPtr); } errorCode = 0; + ReleaseChannelBuffer(bufPtr); break; } @@ -2692,6 +2697,7 @@ FlushChannel( */ DiscardOutputQueued(statePtr); + ReleaseChannelBuffer(bufPtr); continue; } else { wroteSome = 1; @@ -2711,8 +2717,11 @@ FlushChannel( statePtr->outQueueTail = NULL; } RecycleBuffer(statePtr, bufPtr, 0); + bufPtr = NULL; + } + if (bufPtr) { + ReleaseChannelBuffer(bufPtr); } - ReleaseChannelBuffer(bufPtr); } /* Closes "while (1)". */ /* @@ -4026,6 +4035,7 @@ WillRead( { if (chanPtr->typePtr == NULL) { /* Prevent read attempts on a closed channel */ + DiscardInputQueued(chanPtr->state, 0); Tcl_SetErrno(EINVAL); return -1; } @@ -4204,6 +4214,7 @@ Write( if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { + ReleaseChannelBuffer(bufPtr); return -1; } flushed += statePtr->bufSize; diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 14910d7..084cefb 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -349,7 +349,8 @@ Tcl_GetsObjCmd( if (objc == 3) { if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr, TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; + code = TCL_ERROR; + goto done; } Tcl_SetObjResult(interp, Tcl_NewIntObj(lineLen)); } else { diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index 29996ea..6cc33eb 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -298,7 +298,6 @@ TclChannelTransform( } Tcl_DStringFree(&ds); - dataPtr->self = chan; dataPtr->watchMask = 0; dataPtr->mode = mode; dataPtr->timer = NULL; @@ -317,6 +316,7 @@ TclChannelTransform( ReleaseData(dataPtr); return TCL_ERROR; } + Tcl_Preserve(dataPtr->self); /* * At last initialize the transformation at the script level. @@ -437,6 +437,9 @@ ExecuteCallback( break; case TRANSMIT_DOWN: + if (dataPtr->self == NULL) { + break; + } resObj = Tcl_GetObjResult(eval); resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen); Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf, @@ -444,6 +447,9 @@ ExecuteCallback( break; case TRANSMIT_SELF: + if (dataPtr->self == NULL) { + break; + } resObj = Tcl_GetObjResult(eval); resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen); Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen); @@ -579,6 +585,8 @@ TransformCloseProc( * General cleanup. */ + Tcl_Release(dataPtr->self); + dataPtr->self = NULL; ReleaseData(dataPtr); return TCL_OK; } @@ -614,7 +622,7 @@ TransformInputProc( * Should assert(dataPtr->mode & TCL_READABLE); */ - if (toRead == 0) { + if (toRead == 0 || dataPtr->self == NULL) { /* * Catch a no-op. */ @@ -1084,6 +1092,9 @@ TransformWatchProc( * unchanged. */ + if (dataPtr->self == NULL) { + return; + } downChan = Tcl_GetStackedChannel(dataPtr->self); Tcl_GetChannelType(downChan)->watchProc( diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 94428bb..12fa4a0 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1111,6 +1111,7 @@ ReflectClose( ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in * this interp */ Tcl_HashEntry *hPtr; /* Entry in the above map */ + Tcl_ChannelType *tctPtr; if (TclInThreadExit()) { /* @@ -1149,6 +1150,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; } @@ -1213,6 +1219,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 } @@ -2170,14 +2181,6 @@ FreeReflectedChannel( { Channel *chanPtr = (Channel *) rcPtr->chan; - if (chanPtr->typePtr != &tclRChannelType) { - /* - * Delete a cloned ChannelType structure. - */ - - ckfree(chanPtr->typePtr); - chanPtr->typePtr = NULL; - } Tcl_Release(chanPtr); Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); @@ -2873,11 +2876,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); } @@ -2902,8 +2907,14 @@ ForwardProc( Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); - Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); + 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); |