Ticket #7066: boost_1_50_0_current_thread_tls_key.patch
File boost_1_50_0_current_thread_tls_key.patch, 4.2 KB (added by , 10 years ago) |
---|
-
thread.cpp
31 31 { 32 32 namespace 33 33 { 34 #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 35 boost::once_flag current_thread_tls_init_flag; 36 # else37 boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; 34 // Windows CE does not define the TLS_OUT_OF_INDEXES constant. 35 #ifndef TLS_OUT_OF_INDEXES 36 # define BOOST_THREAD_TLS_OUT_OF_INDEXES_DEFINED 37 # define TLS_OUT_OF_INDEXES 0xFFFFFFFF 38 38 #endif 39 #if defined(UNDER_CE) 40 // Windows CE does not define the TLS_OUT_OF_INDEXES constant. 41 DWORD tls_out_of_index=0xFFFFFFFF; 42 #else 43 DWORD tls_out_of_index=TLS_OUT_OF_INDEXES; 44 #endif 45 DWORD current_thread_tls_key=tls_out_of_index; 39 inline DWORD & get_current_thread_tls_key_ref() 40 { 41 // Static variables at global scope are initialized in a random 42 // order. Thus, we may not initialize current_thread_tls_key at a 43 // global scope or any statically allocated thread_specific_ptr 44 // call may fail. Consider: 45 // a) A static (at global scope) thread_specific_ptr is 46 // initialized by some compiler generated code. 47 // b) create_current_thread_tls_key gets called. TlsAlloc() 48 // result is stored to current_thread_tls_key. (Assuming no 49 // errors happen.) 50 // c) Now a static (at global scope) current_thread_tls_key gets 51 // initialized (again, by compiler generated code) and thus 52 // the value we just got from TlsAlloc gets overwritten. 53 // d) Any following set_current_thread_data() calls will fail as 54 // current_thread_tls_key is TLS_OUT_OF_INDEXES. 55 static DWORD current_thread_tls_key=TLS_OUT_OF_INDEXES; 56 return current_thread_tls_key; 57 } 46 58 47 59 void create_current_thread_tls_key() 48 60 { 49 61 tss_cleanup_implemented(); // if anyone uses TSS, we need the cleanup linked in 50 current_thread_tls_key=TlsAlloc();51 BOOST_ASSERT( current_thread_tls_key!=tls_out_of_index);62 get_current_thread_tls_key_ref() = TlsAlloc(); 63 BOOST_ASSERT(get_current_thread_tls_key_ref()!=TLS_OUT_OF_INDEXES); 52 64 } 53 65 54 66 void cleanup_tls_key() 55 67 { 56 if( current_thread_tls_key!=tls_out_of_index)68 if(get_current_thread_tls_key_ref()!=TLS_OUT_OF_INDEXES) 57 69 { 58 TlsFree( current_thread_tls_key);59 current_thread_tls_key=tls_out_of_index;70 TlsFree(get_current_thread_tls_key_ref()); 71 get_current_thread_tls_key_ref() = TLS_OUT_OF_INDEXES; 60 72 } 61 73 } 62 74 63 75 detail::thread_data_base* get_current_thread_data() 64 76 { 65 if( current_thread_tls_key==tls_out_of_index)77 if(get_current_thread_tls_key_ref()==TLS_OUT_OF_INDEXES) 66 78 { 67 79 return 0; 68 80 } 69 return (detail::thread_data_base*)TlsGetValue( current_thread_tls_key);81 return (detail::thread_data_base*)TlsGetValue(get_current_thread_tls_key_ref()); 70 82 } 71 83 72 84 void set_current_thread_data(detail::thread_data_base* new_data) 73 85 { 86 #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 87 static boost::once_flag current_thread_tls_init_flag; 88 #else 89 static boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; 90 #endif 74 91 boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); 75 if( current_thread_tls_key!=tls_out_of_index)76 BOOST_VERIFY(TlsSetValue( current_thread_tls_key,new_data));92 if(get_current_thread_tls_key_ref()!=TLS_OUT_OF_INDEXES) 93 BOOST_VERIFY(TlsSetValue(get_current_thread_tls_key_ref(),new_data)); 77 94 else 78 95 boost::throw_exception(thread_resource_error()); 79 96 } 80 97 98 #ifdef BOOST_THREAD_TLS_OUT_OF_INDEXES_DEFINED 99 # undef TLS_OUT_OF_INDEXES 100 # undef BOOST_THREAD_TLS_OUT_OF_INDEXES_DEFINED 101 #endif 102 81 103 #ifndef BOOST_HAS_THREADEX 82 104 // Windows CE doesn't define _beginthreadex 83 105