summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandreask <andreask>2015-05-22 20:21:48 (GMT)
committerandreask <andreask>2015-05-22 20:21:48 (GMT)
commit5d239b617ecab1d8b54bdfed33cd12522c49938a (patch)
tree37f9e251e1d2ff90c8c36b696a8c4d216182666e
parentac66ecde08cacbe613154be42c2bc55c2a513435 (diff)
downloadtcl-5d239b617ecab1d8b54bdfed33cd12522c49938a.zip
tcl-5d239b617ecab1d8b54bdfed33cd12522c49938a.tar.gz
tcl-5d239b617ecab1d8b54bdfed33cd12522c49938a.tar.bz2
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.
-rw-r--r--generic/tclObj.c46
1 files 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