Boost logo

Boost :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2004-07-28 17:24:33


Roland wrote:
> Now in your module B you have a (global) TSS variable.
> A calls into B.
> When should the TSS be initialized? On first use? I am afraid that is not trivially

You do not need to worry about local thread data for CRT, at least if
you use MSVC. Here is explanation: your library B contains function
DllMain, and it's called just when library got loaded, right? Wrong. If
you linked with CRT (no matter which one - statically or dynamically
linked, multi- or single-threaded, with debug symbols or without), your
entry point is actually _DllMainCRTStartup (use dumpbin.exe to see it).
You may find this function in CRT sources (if you installed it together
with MSVC). In multi-threaded, statically linked version of CRT this
function will indirectly call TlsAlloc (or actually FlsAlloc - if
present in "kernel32.dll", at least in CRT delivered with MSVC71). Index
for CRT local storage has been initialized, what remains is CRT data for
each thread. You are concerned that thread started with CreateThread (or
whatever other API different than "blessed" _beginthread) might not
contain valid CRT data in it's local storage. It's true, but CRT runtime
will receive DLL_THREAD_ATTACH notifications. It will arrive to
_DllMainCRTStartup if you linked CRT statically, otherwise to dynamic
CRT runtime library (BTW, it's entry point is called _CRTDLL_INIT).
There is still possibility that you disabled thread notifications in
your library *and* linked CRT statically. That might be a problem, but
if you grep for _getptd function (again, it's in sources of CRT in your
MSVC directory) you will understand there's no problem at all. This
function is the only way that other CRT functions use to access local
thread storage. It will create and initialize CRT data if current thread
does not contain it yet. Thus all CRT functions requiring access to
local thread data will actually gain it without problem - it will be
created no later than on first access.

Now about release. If you used dynamically linked CRT library, that's no
problem at all. It will receive DLL_THREAD_DETACH and execute _freeptd
in order to free CRT thread data. If you used statically linked CRT
runtime, this notification will arrive to _DllMainCRTStartup (which will
execute _freeptd). There is a problem however if you disable thread
notifications in your library *and* use statically linked CRT. This will
result in memory leak in CRT, documented here :
http://msdn.microsoft.com/library/en-us/dllproc/base/createthread.asp
(see Remarks, bottom of page)

When your library got unloaded from memory, TlsFree (or FlsFree) is
called indirectly in entry point of your library, ie. _DllMainCRTStartup
(if you used statically linked CRT). In case of dynamic CRT library,
it's calling TlsAlloc and TlsFree (or FlsAlloc and FlsFree) in its own
entry point on DLL_PROCESS_ATTACH and DLL_PROCESS_DETTACH - you may find
it in crtlib.c in your MSVC directory.

B.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk