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.
28 * Written by Kai Tietz <kai.tietz@onevision.com>
29 * Based on version created by Mumit Khan <khan@nanotech.wisc.edu>
32 #ifndef WIN32_LEAN_AND_MEAN
33 #define WIN32_LEAN_AND_MEAN
38 WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
39 int ___w64_mingwthr_remove_key_dtor (DWORD key);
40 int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
42 /* To protect the thread/key association data structure modifications. */
43 static CRITICAL_SECTION __mingwthr_cs;
44 static volatile int __mingwthr_cs_init = 0;
46 typedef struct __mingwthr_key __mingwthr_key_t;
48 /* The list of threads active with key/dtor pairs. */
49 struct __mingwthr_key {
52 __mingwthr_key_t volatile *next;
56 static __mingwthr_key_t volatile *key_dtor_list;
59 ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
61 __mingwthr_key_t *new_key;
63 if (__mingwthr_cs_init == 0)
65 new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
72 EnterCriticalSection (&__mingwthr_cs);
74 new_key->next = key_dtor_list;
75 key_dtor_list = new_key;
77 LeaveCriticalSection (&__mingwthr_cs);
82 ___w64_mingwthr_remove_key_dtor (DWORD key)
84 __mingwthr_key_t volatile *prev_key;
85 __mingwthr_key_t volatile *cur_key;
87 if (__mingwthr_cs_init == 0)
90 EnterCriticalSection (&__mingwthr_cs);
93 cur_key = key_dtor_list;
95 while (cur_key != NULL)
97 if ( cur_key->key == key)
100 key_dtor_list = cur_key->next;
102 prev_key->next = cur_key->next;
104 free ((void*)cur_key);
108 cur_key = cur_key->next;
111 LeaveCriticalSection (&__mingwthr_cs);
116 __mingwthr_run_key_dtors (void)
118 __mingwthr_key_t volatile *keyp;
120 if (__mingwthr_cs_init == 0)
122 EnterCriticalSection (&__mingwthr_cs);
124 for (keyp = key_dtor_list; keyp; )
126 LPVOID value = TlsGetValue (keyp->key);
127 if (GetLastError () == ERROR_SUCCESS)
130 (*keyp->dtor) (value);
135 LeaveCriticalSection (&__mingwthr_cs);
139 __mingw_TLScallback (HANDLE hDllHandle __attribute__ ((__unused__)),
141 LPVOID reserved __attribute__ ((__unused__)))
145 case DLL_PROCESS_ATTACH:
146 if (__mingwthr_cs_init == 0)
147 InitializeCriticalSection (&__mingwthr_cs);
148 __mingwthr_cs_init = 1;
150 case DLL_PROCESS_DETACH:
151 __mingwthr_run_key_dtors();
152 if (__mingwthr_cs_init == 1)
154 __mingwthr_cs_init = 0;
155 DeleteCriticalSection (&__mingwthr_cs);
158 case DLL_THREAD_ATTACH:
160 case DLL_THREAD_DETACH:
161 __mingwthr_run_key_dtors();