2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER within this package.
6 * Written by Kai Tietz <kai.tietz@onevision.com>
8 * This file is used by if gcc is built with --enable-threads=win32.
10 * Based on version created by Mumit Khan <khan@nanotech.wisc.edu>
14 #ifndef WIN32_LEAN_AND_MEAN
15 #define WIN32_LEAN_AND_MEAN
20 WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
21 int ___w64_mingwthr_remove_key_dtor (DWORD key);
22 int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
24 /* To protect the thread/key association data structure modifications. */
25 static CRITICAL_SECTION __mingwthr_cs;
26 static volatile int __mingwthr_cs_init = 0;
28 typedef struct __mingwthr_key __mingwthr_key_t;
30 /* The list of threads active with key/dtor pairs. */
31 struct __mingwthr_key {
34 __mingwthr_key_t volatile *next;
38 static __mingwthr_key_t volatile *key_dtor_list;
41 ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
43 __mingwthr_key_t *new_key;
45 if (__mingwthr_cs_init == 0)
47 new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
54 EnterCriticalSection (&__mingwthr_cs);
56 new_key->next = key_dtor_list;
57 key_dtor_list = new_key;
59 LeaveCriticalSection (&__mingwthr_cs);
64 ___w64_mingwthr_remove_key_dtor (DWORD key)
66 __mingwthr_key_t volatile *prev_key;
67 __mingwthr_key_t volatile *cur_key;
69 if (__mingwthr_cs_init == 0)
72 EnterCriticalSection (&__mingwthr_cs);
75 cur_key = key_dtor_list;
77 while (cur_key != NULL)
79 if ( cur_key->key == key)
82 key_dtor_list = cur_key->next;
84 prev_key->next = cur_key->next;
86 free ((void*)cur_key);
90 cur_key = cur_key->next;
93 LeaveCriticalSection (&__mingwthr_cs);
98 __mingwthr_run_key_dtors (void)
100 __mingwthr_key_t volatile *keyp;
102 if (__mingwthr_cs_init == 0)
104 EnterCriticalSection (&__mingwthr_cs);
106 for (keyp = key_dtor_list; keyp; )
108 LPVOID value = TlsGetValue (keyp->key);
109 if (GetLastError () == ERROR_SUCCESS)
112 (*keyp->dtor) (value);
117 LeaveCriticalSection (&__mingwthr_cs);
121 __mingw_TLScallback (HANDLE hDllHandle __attribute__ ((__unused__)),
123 LPVOID reserved __attribute__ ((__unused__)))
127 case DLL_PROCESS_ATTACH:
128 if (__mingwthr_cs_init == 0)
129 InitializeCriticalSection (&__mingwthr_cs);
130 __mingwthr_cs_init = 1;
132 case DLL_PROCESS_DETACH:
133 __mingwthr_run_key_dtors();
134 if (__mingwthr_cs_init == 1)
136 __mingwthr_cs_init = 0;
137 DeleteCriticalSection (&__mingwthr_cs);
140 case DLL_THREAD_ATTACH:
142 case DLL_THREAD_DETACH:
143 __mingwthr_run_key_dtors();