3 * @copy 2012 MinGW.org project
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
26 * This file is used by if gcc is built with --enable-threads=win32.
29 #ifndef WIN32_LEAN_AND_MEAN
30 #define WIN32_LEAN_AND_MEAN
35 WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
36 int ___w64_mingwthr_remove_key_dtor (DWORD key);
37 int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
39 /* To protect the thread/key association data structure modifications. */
40 static CRITICAL_SECTION __mingwthr_cs;
41 static volatile int __mingwthr_cs_init = 0;
43 typedef struct __mingwthr_key __mingwthr_key_t;
45 /* The list of threads active with key/dtor pairs. */
46 struct __mingwthr_key {
49 __mingwthr_key_t volatile *next;
53 static __mingwthr_key_t volatile *key_dtor_list;
56 ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
58 __mingwthr_key_t *new_key;
60 if (__mingwthr_cs_init == 0)
62 new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
69 EnterCriticalSection (&__mingwthr_cs);
71 new_key->next = key_dtor_list;
72 key_dtor_list = new_key;
74 LeaveCriticalSection (&__mingwthr_cs);
79 ___w64_mingwthr_remove_key_dtor (DWORD key)
81 __mingwthr_key_t volatile *prev_key;
82 __mingwthr_key_t volatile *cur_key;
84 if (__mingwthr_cs_init == 0)
87 EnterCriticalSection (&__mingwthr_cs);
90 cur_key = key_dtor_list;
92 while (cur_key != NULL)
94 if ( cur_key->key == key)
97 key_dtor_list = cur_key->next;
99 prev_key->next = cur_key->next;
101 free ((void*)cur_key);
105 cur_key = cur_key->next;
108 LeaveCriticalSection (&__mingwthr_cs);
113 __mingwthr_run_key_dtors (void)
115 __mingwthr_key_t volatile *keyp;
117 if (__mingwthr_cs_init == 0)
119 EnterCriticalSection (&__mingwthr_cs);
121 for (keyp = key_dtor_list; keyp; )
123 LPVOID value = TlsGetValue (keyp->key);
124 if (GetLastError () == ERROR_SUCCESS)
127 (*keyp->dtor) (value);
132 LeaveCriticalSection (&__mingwthr_cs);
136 __mingw_TLScallback (HANDLE hDllHandle __attribute__ ((__unused__)),
138 LPVOID reserved __attribute__ ((__unused__)))
142 case DLL_PROCESS_ATTACH:
143 if (__mingwthr_cs_init == 0)
144 InitializeCriticalSection (&__mingwthr_cs);
145 __mingwthr_cs_init = 1;
147 case DLL_PROCESS_DETACH:
148 __mingwthr_run_key_dtors();
149 if (__mingwthr_cs_init == 1)
151 __mingwthr_cs_init = 0;
152 DeleteCriticalSection (&__mingwthr_cs);
155 case DLL_THREAD_ATTACH:
157 case DLL_THREAD_DETACH:
158 __mingwthr_run_key_dtors();