summaryrefslogtreecommitdiffstats
path: root/generic
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 /generic
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.
Diffstat (limited to 'generic')
-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