[thread] use of __declspec(thread)

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

David Deakins wrote:
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',
Yes I know. This is one of the reasons why the thread_specific_ptr uses TLSAlloc... Family of functions. Also the mingw compiler crew decided to use these API functions to implement __thread keyword. Unfortunately Anthony did not contact me up-front on this matter, but I am sure it will be easy enough for him to either change this to use thread_specific_ptr or the TLSxxx family of functions. @Anthony: are you listening? Roland aka speedsnail
participants (2)
-
David Deakins
-
Roland Schwarz