
Roland wrote:
TlsSetValue and initialization of CRT data is delayed to first access of CRT TLS data through _getptd function (defined in tidtable.c).
Ahhh. Now I understand what you are talking about! You convinced me.
:-)
During DLL_THREAD_DETACH the _tiddata has already been deallocated during _endthread. Now if one again accesses one of the CRT functions during DLL_THREAD_DEATCH this would cause _getptd to reallocate _tiddata for this thread. Hmm. This will also account for a memory leak. Wouldn't it?
Probably yes. But : * if CRT is statically linked to dynamic library, user's DllMain is called prior to releasing CRT data * if CRT is dynamically linked to program or some of it's libraries, I think that it will receive DLL_THREAD_DETACH notification after user dynamic libraries handled it (reverse order of loading libraries). I'm not sure about that. You would still have memory leak if using staticaly linked CRT *and* nobody is handling DLL_THREAD_DETACH for this TLS CRT index. But that does not apply to Windows Server 2003, see below. In case of Windows Server 2003 there is callback function called FlsCallback, documented here: http://msdn.microsoft.com/library/en-us/dllproc/base/flscallback.asp It's called inside ThreadExit, in context of exiting thread, *after* all DLLs received notification DLL_THREAD_DETACH. Actually, CRT in MSVC71 is using Fls* functions if available; function _freefls (defined by CRT) will be called to *reliably* release CRT TLS (or actually fiber local storage) on Windows Server 2003. You may find that in file tidtable.c (available with MSVC71, directory vc7/crt/src). I'm seeking for a way to achieve similar functionality in little older versions of Windows - but it might be quite difficult.
While the situation is not as bad as I was afraid it could be, it still would be better to be able to call the tls cleanup code from within _endthread, and not DLL_THREAD_DETACH.
Hm, _endthread is executed before notifications DLL_THREAD_DETACH are sent in ExitThread. Or more precisely - ExitThread is called at the end of _endthread, and there is no way one could execute code after this call. Thus if user DllMain is expecting to find data that has been released in _endthread, that might be a problem (eg. in case of CRT - another allocation inside _getptd). B.