@@ -35,7 +35,7 @@ extern char __mingw_module_is_dll;
3535static CRITICAL_SECTION lock ;
3636static int inited = 0 ;
3737static dtor_obj * global_dtors = NULL ;
38- static __thread dtor_obj * tls_dtors = NULL ;
38+ static DWORD tls_dtors_slot = TLS_OUT_OF_INDEXES ;
3939
4040int __mingw_cxa_atexit (dtor_fn dtor , void * obj , void * dso ) {
4141 if (!inited )
@@ -73,24 +73,29 @@ int __mingw_cxa_thread_atexit(dtor_fn dtor, void *obj, void *dso) {
7373 return 1 ;
7474 handler -> dtor = dtor ;
7575 handler -> obj = obj ;
76- handler -> next = tls_dtors ;
77- tls_dtors = handler ;
76+ handler -> next = ( dtor_obj * ) TlsGetValue ( tls_dtors_slot ) ;
77+ TlsSetValue ( tls_dtors_slot , handler ) ;
7878 return 0 ;
7979}
8080
8181static void WINAPI tls_atexit_callback (HANDLE __UNUSED_PARAM (hDllHandle ), DWORD dwReason , LPVOID __UNUSED_PARAM (lpReserved )) {
8282 if (dwReason == DLL_PROCESS_DETACH ) {
83- run_dtor_list (& tls_dtors );
83+ dtor_obj * p = (dtor_obj * )TlsGetValue (tls_dtors_slot );
84+ run_dtor_list (& p );
85+ TlsSetValue (tls_dtors_slot , p );
86+ TlsFree (tls_dtors_slot );
8487 run_dtor_list (& global_dtors );
8588 }
8689}
8790
8891static void WINAPI tls_callback (HANDLE hDllHandle , DWORD dwReason , LPVOID __UNUSED_PARAM (lpReserved )) {
92+ dtor_obj * p ;
8993 switch (dwReason ) {
9094 case DLL_PROCESS_ATTACH :
9195 if (inited == 0 ) {
9296 InitializeCriticalSection (& lock );
9397 __dso_handle = hDllHandle ;
98+ tls_dtors_slot = TlsAlloc ();
9499 /*
95100 * We can only call _register_thread_local_exe_atexit_callback once
96101 * in a process; if we call it a second time the process terminates.
@@ -124,16 +129,19 @@ static void WINAPI tls_callback(HANDLE hDllHandle, DWORD dwReason, LPVOID __UNUS
124129 * main, or when a DLL is unloaded), and when exiting bypassing some of
125130 * the cleanup, by calling _exit or ExitProcess. In the latter cases,
126131 * destructors (both TLS and global) in loaded DLLs still get called,
127- * but only TLS destructors get called for the main executable, global
128- * variables' destructors don't run. (This matches what MSVC does with
129- * a dynamically linked CRT.)
132+ * but none get called for the main executable. This matches what the
133+ * standard says, but differs from what MSVC does with a dynamically
134+ * linked CRT (which still runs TLS destructors for the main thread).
130135 */
131- run_dtor_list (& tls_dtors );
132136 if (__mingw_module_is_dll ) {
137+ p = (dtor_obj * )TlsGetValue (tls_dtors_slot );
138+ run_dtor_list (& p );
139+ TlsSetValue (tls_dtors_slot , p );
133140 /* For DLLs, run dtors when detached. For EXEs, run dtors via the
134141 * thread local atexit callback, to make sure they don't run when
135142 * exiting the process with _exit or ExitProcess. */
136143 run_dtor_list (& global_dtors );
144+ TlsFree (tls_dtors_slot );
137145 }
138146 if (inited == 1 ) {
139147 inited = 0 ;
@@ -143,9 +151,11 @@ static void WINAPI tls_callback(HANDLE hDllHandle, DWORD dwReason, LPVOID __UNUS
143151 case DLL_THREAD_ATTACH :
144152 break ;
145153 case DLL_THREAD_DETACH :
146- run_dtor_list (& tls_dtors );
154+ p = (dtor_obj * )TlsGetValue (tls_dtors_slot );
155+ run_dtor_list (& p );
156+ TlsSetValue (tls_dtors_slot , p );
147157 break ;
148158 }
149159}
150160
151- _CRTALLOC (".CRT$XLE " ) PIMAGE_TLS_CALLBACK __xl_e = (PIMAGE_TLS_CALLBACK ) tls_callback ;
161+ _CRTALLOC (".CRT$XLB " ) PIMAGE_TLS_CALLBACK __xl_b = (PIMAGE_TLS_CALLBACK ) tls_callback ;
0 commit comments