Boost logo

Boost :

From: David Deakins (ddeakins_at_[hidden])
Date: 2007-11-16 01:03:57


I have been testing the rewritten code for the thread library on one of
our applications. On this project we create a Windows DLL that
internally uses Boost.Thread to spawn worker threads. I noticed that
when some applications make use of the DLL, access violations are
generated in set_current_thread_data() in win32/thread.cpp.
current_thread_data was resolving to an address of 0. After some
investigation the source of the problem turned out to be that
__declspec(thread) cannot be used in a DLL if the DLL might be loaded
using LoadLibrary. Per the Microsoft 'Rules and Limitations for TLS',

   If a DLL declares any nonlocal data or object as __declspec( thread ),
   it can cause a protection fault if dynamically loaded. After the DLL
   is loaded with LoadLibrary, it causes system failure whenever the code
   references the nonlocal __declspec( thread ) data. Because the global
   variable space for a thread is allocated at run time, the size of this
   space is based on a calculation of the requirements of the application
   plus the requirements of all the DLLs that are statically linked. When
   you use LoadLibrary, there is no way to extend this space to allow for
   the thread local variables declared with __declspec( thread ). Use the
   TLS APIs, such as TlsAlloc, in your DLL to allocate TLS if the DLL
   might be loaded with LoadLibrary.

In our situation this is unfortunate, because the DLL is used with an
optional component and we prefer not to require the DLL to be present
when the optional component is not active. In light of this
restriction, is it necessary to use __declspec(thread) for the
current_thread_data variable or is the alternate boost::once
implementation satisfactory? What improvements does the __declspec
version offer over boost::once?

Thanks,
-Dave


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