1*c2c66affSColin Finck /**
2*c2c66affSColin Finck * This file has no copyright assigned and is placed in the Public Domain.
3*c2c66affSColin Finck * This file is part of the w64 mingw-runtime package.
4*c2c66affSColin Finck * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5*c2c66affSColin Finck *
6*c2c66affSColin Finck * Written by Kai Tietz <kai.tietz@onevision.com>
7*c2c66affSColin Finck *
8*c2c66affSColin Finck * This file is used by if gcc is built with --enable-threads=win32.
9*c2c66affSColin Finck *
10*c2c66affSColin Finck * Based on version created by Mumit Khan <khan@nanotech.wisc.edu>
11*c2c66affSColin Finck *
12*c2c66affSColin Finck */
13*c2c66affSColin Finck
14*c2c66affSColin Finck /*#ifndef WIN32_LEAN_AND_MEAN
15*c2c66affSColin Finck #define WIN32_LEAN_AND_MEAN
16*c2c66affSColin Finck #endif
17*c2c66affSColin Finck #include <windows.h>*/
18*c2c66affSColin Finck #include <stdlib.h>
19*c2c66affSColin Finck #include <stdarg.h>
20*c2c66affSColin Finck #include <windef.h>
21*c2c66affSColin Finck #include <winbase.h>
22*c2c66affSColin Finck
23*c2c66affSColin Finck WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved);
24*c2c66affSColin Finck int ___w64_mingwthr_remove_key_dtor (DWORD key);
25*c2c66affSColin Finck int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *));
26*c2c66affSColin Finck
27*c2c66affSColin Finck /* To protect the thread/key association data structure modifications. */
28*c2c66affSColin Finck static CRITICAL_SECTION __mingwthr_cs;
29*c2c66affSColin Finck static volatile int __mingwthr_cs_init = 0;
30*c2c66affSColin Finck
31*c2c66affSColin Finck typedef struct __mingwthr_key __mingwthr_key_t;
32*c2c66affSColin Finck
33*c2c66affSColin Finck /* The list of threads active with key/dtor pairs. */
34*c2c66affSColin Finck struct __mingwthr_key {
35*c2c66affSColin Finck DWORD key;
36*c2c66affSColin Finck void (*dtor)(void *);
37*c2c66affSColin Finck __mingwthr_key_t volatile *next;
38*c2c66affSColin Finck };
39*c2c66affSColin Finck
40*c2c66affSColin Finck
41*c2c66affSColin Finck static __mingwthr_key_t volatile *key_dtor_list;
42*c2c66affSColin Finck
43*c2c66affSColin Finck int
___w64_mingwthr_add_key_dtor(DWORD key,void (* dtor)(void *))44*c2c66affSColin Finck ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
45*c2c66affSColin Finck {
46*c2c66affSColin Finck __mingwthr_key_t *new_key;
47*c2c66affSColin Finck
48*c2c66affSColin Finck if (__mingwthr_cs_init == 0)
49*c2c66affSColin Finck return 0;
50*c2c66affSColin Finck new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
51*c2c66affSColin Finck if (new_key == NULL)
52*c2c66affSColin Finck return -1;
53*c2c66affSColin Finck
54*c2c66affSColin Finck new_key->key = key;
55*c2c66affSColin Finck new_key->dtor = dtor;
56*c2c66affSColin Finck
57*c2c66affSColin Finck EnterCriticalSection (&__mingwthr_cs);
58*c2c66affSColin Finck
59*c2c66affSColin Finck new_key->next = key_dtor_list;
60*c2c66affSColin Finck key_dtor_list = new_key;
61*c2c66affSColin Finck
62*c2c66affSColin Finck LeaveCriticalSection (&__mingwthr_cs);
63*c2c66affSColin Finck return 0;
64*c2c66affSColin Finck }
65*c2c66affSColin Finck
66*c2c66affSColin Finck int
___w64_mingwthr_remove_key_dtor(DWORD key)67*c2c66affSColin Finck ___w64_mingwthr_remove_key_dtor (DWORD key)
68*c2c66affSColin Finck {
69*c2c66affSColin Finck __mingwthr_key_t volatile *prev_key;
70*c2c66affSColin Finck __mingwthr_key_t volatile *cur_key;
71*c2c66affSColin Finck
72*c2c66affSColin Finck if (__mingwthr_cs_init == 0)
73*c2c66affSColin Finck return 0;
74*c2c66affSColin Finck
75*c2c66affSColin Finck EnterCriticalSection (&__mingwthr_cs);
76*c2c66affSColin Finck
77*c2c66affSColin Finck prev_key = NULL;
78*c2c66affSColin Finck cur_key = key_dtor_list;
79*c2c66affSColin Finck
80*c2c66affSColin Finck while (cur_key != NULL)
81*c2c66affSColin Finck {
82*c2c66affSColin Finck if ( cur_key->key == key)
83*c2c66affSColin Finck {
84*c2c66affSColin Finck if (prev_key == NULL)
85*c2c66affSColin Finck key_dtor_list = cur_key->next;
86*c2c66affSColin Finck else
87*c2c66affSColin Finck prev_key->next = cur_key->next;
88*c2c66affSColin Finck
89*c2c66affSColin Finck free ((void*)cur_key);
90*c2c66affSColin Finck break;
91*c2c66affSColin Finck }
92*c2c66affSColin Finck prev_key = cur_key;
93*c2c66affSColin Finck cur_key = cur_key->next;
94*c2c66affSColin Finck }
95*c2c66affSColin Finck
96*c2c66affSColin Finck LeaveCriticalSection (&__mingwthr_cs);
97*c2c66affSColin Finck return 0;
98*c2c66affSColin Finck }
99*c2c66affSColin Finck
100*c2c66affSColin Finck static void
__mingwthr_run_key_dtors(void)101*c2c66affSColin Finck __mingwthr_run_key_dtors (void)
102*c2c66affSColin Finck {
103*c2c66affSColin Finck __mingwthr_key_t volatile *keyp;
104*c2c66affSColin Finck
105*c2c66affSColin Finck if (__mingwthr_cs_init == 0)
106*c2c66affSColin Finck return;
107*c2c66affSColin Finck EnterCriticalSection (&__mingwthr_cs);
108*c2c66affSColin Finck
109*c2c66affSColin Finck for (keyp = key_dtor_list; keyp; )
110*c2c66affSColin Finck {
111*c2c66affSColin Finck LPVOID value = TlsGetValue (keyp->key);
112*c2c66affSColin Finck if (GetLastError () == ERROR_SUCCESS)
113*c2c66affSColin Finck {
114*c2c66affSColin Finck if (value)
115*c2c66affSColin Finck (*keyp->dtor) (value);
116*c2c66affSColin Finck }
117*c2c66affSColin Finck keyp = keyp->next;
118*c2c66affSColin Finck }
119*c2c66affSColin Finck
120*c2c66affSColin Finck LeaveCriticalSection (&__mingwthr_cs);
121*c2c66affSColin Finck }
122*c2c66affSColin Finck
123*c2c66affSColin Finck WINBOOL
__mingw_TLScallback(HANDLE __UNUSED_PARAM (hDllHandle),DWORD reason,LPVOID __UNUSED_PARAM (reserved))124*c2c66affSColin Finck __mingw_TLScallback (HANDLE __UNUSED_PARAM(hDllHandle),
125*c2c66affSColin Finck DWORD reason,
126*c2c66affSColin Finck LPVOID __UNUSED_PARAM(reserved))
127*c2c66affSColin Finck {
128*c2c66affSColin Finck switch (reason)
129*c2c66affSColin Finck {
130*c2c66affSColin Finck case DLL_PROCESS_ATTACH:
131*c2c66affSColin Finck if (__mingwthr_cs_init == 0)
132*c2c66affSColin Finck InitializeCriticalSection (&__mingwthr_cs);
133*c2c66affSColin Finck __mingwthr_cs_init = 1;
134*c2c66affSColin Finck break;
135*c2c66affSColin Finck case DLL_PROCESS_DETACH:
136*c2c66affSColin Finck __mingwthr_run_key_dtors();
137*c2c66affSColin Finck if (__mingwthr_cs_init == 1)
138*c2c66affSColin Finck {
139*c2c66affSColin Finck __mingwthr_cs_init = 0;
140*c2c66affSColin Finck DeleteCriticalSection (&__mingwthr_cs);
141*c2c66affSColin Finck }
142*c2c66affSColin Finck break;
143*c2c66affSColin Finck case DLL_THREAD_ATTACH:
144*c2c66affSColin Finck break;
145*c2c66affSColin Finck case DLL_THREAD_DETACH:
146*c2c66affSColin Finck __mingwthr_run_key_dtors();
147*c2c66affSColin Finck break;
148*c2c66affSColin Finck }
149*c2c66affSColin Finck return TRUE;
150*c2c66affSColin Finck }
151*c2c66affSColin Finck
152