From 907aebaab8fa670337c01ce70b784d5805e01f77 Mon Sep 17 00:00:00 2001 From: andreask Date: Fri, 22 May 2015 20:21:48 +0000 Subject: Moved Tcl_Obj* objThreadMap release tracking to a location where regular packages will call through, enabling their full tracking by the core, and thus avoiding the "expected to create new entry for object map" panic seen otherwise. --- generic/tclObj.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index 96a4082..037bd76 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1315,6 +1315,38 @@ TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { register Tcl_ObjType *typePtr = objPtr->typePtr; +# ifdef TCL_THREADS + /* + * Check to make sure that the Tcl_Obj was allocated by the current + * thread. Don't do this check when shutting down since thread local + * storage can be finalized before the last Tcl_Obj is freed. + */ + + if (!TclInExit()) { + Tcl_HashTable *tablePtr; + Tcl_HashEntry *hPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + tablePtr = tsdPtr->objThreadMap; + if (!tablePtr) { + Tcl_Panic("TclFreeObj: object table not initialized"); + } + hPtr = Tcl_FindHashEntry(tablePtr, (char *) objPtr); + if (hPtr) { + /* + * As the Tcl_Obj is going to be deleted we remove the entry. + */ + + ObjData *objData = Tcl_GetHashValue(hPtr); + + if (objData != NULL) { + ckfree((char *) objData); + } + + Tcl_DeleteHashEntry(hPtr); + } + } +# endif /* * This macro declares a variable, so must come here... @@ -3715,20 +3747,6 @@ Tcl_DbDecrRefCount( "Trying to decr ref count of " "Tcl_Obj allocated in another thread"); } - - /* - * If the Tcl_Obj is going to be deleted, remove the entry. - */ - - if ((objPtr->refCount - 1) <= 0) { - ObjData *objData = Tcl_GetHashValue(hPtr); - - if (objData != NULL) { - ckfree((char *) objData); - } - - Tcl_DeleteHashEntry(hPtr); - } } # endif #endif -- cgit v0.12 From 17420ef9f04b1e785a91da0d8e10a36eed8a9079 Mon Sep 17 00:00:00 2001 From: Joe Mistachkin Date: Fri, 22 May 2015 23:26:29 +0000 Subject: Minor compilation issue fix, make sure variable declaration (via macro) is first. --- generic/tclObj.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index 037bd76..36687fa 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1315,6 +1315,13 @@ TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { register Tcl_ObjType *typePtr = objPtr->typePtr; + + /* + * This macro declares a variable, so must come here... + */ + + ObjInitDeletionContext(context); + # ifdef TCL_THREADS /* * Check to make sure that the Tcl_Obj was allocated by the current @@ -1349,12 +1356,6 @@ TclFreeObj( # endif /* - * This macro declares a variable, so must come here... - */ - - ObjInitDeletionContext(context); - - /* * Check for a double free of the same value. This is slightly tricky * because it is customary to free a Tcl_Obj when its refcount falls * either from 1 to 0, or from 0 to -1. Falling from -1 to -2, though, -- cgit v0.12