I came across this old message while going through my inbox looking for
AOLserver 3.3 issues to check on in the next ArsDigita release:
+---------- On Mar 2, Zoran Vasiljevic said:
> Obviously, somebody has forgotten to add this
> line when re-implementing TclpThreadDataKeyInit().
> It results in leak on thread-exit each time a TSD is
> involved (used on many places within Tcl itself and
> also in some new thread-aware Tcl extensions).
>
> I have re-checked the change with Purify under Solaris 2.5.1
> but I do not think it has something to do with the OS at all.
> It is not leaking any more, though.
>
> Can somebody please look into this and if it's ok
> include it in 3.3 ? I have checked the CVS on
> SourceForge but the current version is still broken.
>
> Anyway, ...
>
> NS_EXPORT void
> TclpThreadDataKeyInit(keyPtr)
> Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk */
> {
> Ns_Tls *pkeyPtr;
>
> MASTER_LOCK;
> if (*keyPtr == NULL) {
> pkeyPtr = (Ns_Tls *)ns_malloc(sizeof(Ns_Tls));
> Ns_TlsAlloc(pkeyPtr, NULL);
> *keyPtr = (Tcl_ThreadDataKey)pkeyPtr;
> /*-->*/ TclRememberDataKey(keyPtr); /* so it's freed on thread-exit */
> }
> MASTER_UNLOCK;
> }
It looks like this is no longer an issue in 3.3.1.
TclpThreadDataKeyInit in thread/tcl8x.c has been rewritten:
NS_EXPORT void
TclpThreadDataKeyInit(keyPtr)
Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk */
{
Ns_Tls *tlsPtr = (Ns_Tls *) keyPtr;
Ns_MasterLock();
if (*tlsPtr == NULL) {
Ns_TlsAlloc(tlsPtr, FreeDataBlock);
}
Ns_MasterUnlock();
}
It now passes FreeDataBlock to Ns_TclAlloc, so NsCleanupTls will call it
for each Tcl TLS at thread cleanup time. FreeDataBlock calls TclpFree
on the TLS.