diff options
author | mdejong <mdejong> | 2003-07-22 00:59:57 (GMT) |
---|---|---|
committer | mdejong <mdejong> | 2003-07-22 00:59:57 (GMT) |
commit | ce198068acc4ff17e7c6d6b2ab4278ee933ec117 (patch) | |
tree | d3afea75fc0d6fc2565a51ce9f8b3e99ce8d3dc6 /generic/tclInt.h | |
parent | 2fef44444804c9b45a356ef18edc4254a7805b6f (diff) | |
download | tcl-ce198068acc4ff17e7c6d6b2ab4278ee933ec117.zip tcl-ce198068acc4ff17e7c6d6b2ab4278ee933ec117.tar.gz tcl-ce198068acc4ff17e7c6d6b2ab4278ee933ec117.tar.bz2 |
Check that the thread incrementing or decrementing
the ref count of a Tcl_Obj is the thread that
originally allocated the thread. This fail fast
behavior will catch programming errors that
allow a single Tcl_Obj to be accessed from multiple
threads.
* generic/tcl.h (Tcl_Obj): Add allocThread member
to Tcl_Obj. This member records the thread id the
Tcl_Obj was allocated. It is used to check that
any future ref count incr or decr is done from
the same thread that allocated the Tcl_Obj.
This member is defined only when threads and
mem debug are enabled.
* generic/tclInt.h (TclNewObj, TclDbNewObj,
TclDecrRefCount):
Define TclNewObj and TclDbNewObj using TclDbInitNewObj
when mem debug is enabled. This fixes a problem where
TclNewObj calls did not work the same as TclDbNewObj
when mem debug was enabled.
* generic/tclObj.c (TclDbInitNewObj, Tcl_DbIncrRefCount,
Tcl_DbDecrRefCount): Add new helper to init Tcl_Obj
members when mem debug is enabled. Init the allocThread
member in TclDbInitNewObj and check it in
Tcl_DbIncrRefCount and Tcl_DbDecrRefCount to make sure
a Tcl_Obj allocated in one thread is not being acted
upon in another thread.
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r-- | generic/tclInt.h | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index 02987c2..040e359 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclInt.h,v 1.128 2003/06/09 22:48:32 andreas_kupries Exp $ + * RCS: @(#) $Id: tclInt.h,v 1.129 2003/07/22 00:59:58 mdejong Exp $ */ #ifndef _TCLINT @@ -2087,15 +2087,16 @@ EXTERN Tcl_Obj *TclPtrIncrWideVar _ANSI_ARGS_((Tcl_Interp *interp, Var *varPtr, # define TclIncrObjsFreed() #endif /* TCL_COMPILE_STATS */ -#define TclNewObj(objPtr) \ - TclAllocObjStorage(objPtr); \ +#ifndef TCL_MEM_DEBUG +# define TclNewObj(objPtr) \ TclIncrObjsAllocated(); \ + TclAllocObjStorage(objPtr); \ (objPtr)->refCount = 0; \ (objPtr)->bytes = tclEmptyStringRep; \ (objPtr)->length = 0; \ (objPtr)->typePtr = NULL -#define TclDecrRefCount(objPtr) \ +# define TclDecrRefCount(objPtr) \ if (--(objPtr)->refCount <= 0) { \ if (((objPtr)->typePtr != NULL) \ && ((objPtr)->typePtr->freeIntRepProc != NULL)) { \ @@ -2108,27 +2109,22 @@ EXTERN Tcl_Obj *TclPtrIncrWideVar _ANSI_ARGS_((Tcl_Interp *interp, Var *varPtr, TclFreeObjStorage(objPtr); \ TclIncrObjsFreed(); \ } +#endif /* TCL_MEM_DEBUG */ #ifdef TCL_MEM_DEBUG -# define TclAllocObjStorage(objPtr) \ - (objPtr) = (Tcl_Obj *) \ - Tcl_DbCkalloc(sizeof(Tcl_Obj), __FILE__, __LINE__) +EXTERN void TclDbInitNewObj _ANSI_ARGS_((Tcl_Obj *objPtr)); + +# define TclDbNewObj(objPtr, file, line) \ + TclIncrObjsAllocated(); \ + (objPtr) = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \ + TclDbInitNewObj(objPtr); + +# define TclNewObj(objPtr) \ + TclDbNewObj(objPtr, __FILE__, __LINE__); + +# define TclDecrRefCount(objPtr) \ + Tcl_DecrRefCount(objPtr); -# define TclFreeObjStorage(objPtr) \ - if ((objPtr)->refCount < -1) { \ - panic("Reference count for %lx was negative: %s line %d", \ - (objPtr), __FILE__, __LINE__); \ - } \ - ckfree((char *) (objPtr)) - -# define TclDbNewObj(objPtr, file, line) \ - (objPtr) = (Tcl_Obj *) Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line)); \ - (objPtr)->refCount = 0; \ - (objPtr)->bytes = tclEmptyStringRep; \ - (objPtr)->length = 0; \ - (objPtr)->typePtr = NULL; \ - TclIncrObjsAllocated() - #elif defined(PURIFY) /* |