
Le 02/07/12 10:50, Pekka Seppänen a écrit :
Hi,
Currently Threads's Win32 TLS implementation uses a global static variable thread::current_thread_tls_key that is defined in src/win32/thread.cpp. As you may know, static variables have a tendency of not being allocated in a very specific order.
Say, that you have a statically allocated class A that ends up calling thread::set_current_thread_data() (eg. uses thread::thread_specific_ptr). If compiler initializes this class before it initializes current_thread_tls_key (this did happen to me on MSVC9) things go boom:
a) Compiler initializes class A, thread::set_current_thread_data() is called, thread::create_current_thread_tls_key() is called once (as expected) and ::TlsAlloc() result is stored to thread::current_thread_tls_key.
b) Compiler initializes thread::current_thread_tls_key, TLS_OUT_OF_INDEXES is stored and, as you may guess,
c) Any following thread::set_current_thread_data calls will fail as the proper result from ::TlsAlloc() was overwritten.
Don't know why this haven't happened before, as previous versions use a static variable, too. Maybe some compilers (MSVC in this case) omit initialization code unless initial value is a non-zero (as with TLS_OUT_OF_INDEXES [0xffffffff] in this case) value.
I propose that thread::current_thread_tls_key is moved to a static function that sole purpose is to return reference to that variable (and thus ensure that current_thread_tls_key is initialized before it is used for the first time). Also, move thread::current_thread_tls_init_flag to thread::set_current_thread_data() to make sure this won't happen to that, too.
Attached a patch that does the above trick (did move TLS_OUT_OF_INDEXES back to a macro as otherwise the code got too cumbersome, does get undef'd unless it was already defined by Winapi). If you like it, I can submit a ticket to Trac that includes the patch.
(Haven't looked what happens during destruction, but guess it's not safe to use TLS features thru Thread.)
Hi, Thanks for the report and the deep analysis. Please, create a ticket, I will give it a try soon. A test case that shows the problem and that your patch is a solution would be much appreciated. Best, Vicente