OSDN Git Service

Manual resolution for LICENSE for files already containing a file
[mingw/mingw-org-wsl.git] / src / libcrt / crt / tlsthrd.c
1 /**
2  * @file tlsthrd.c
3  * @copy 2012 MinGW.org project
4  *
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:
11  * 
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
14  * Software.
15  * 
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.
23  */
24
25 /*
26  * This file is used by if gcc is built with --enable-threads=win32.
27  */
28
29 #ifndef WIN32_LEAN_AND_MEAN
30 #define WIN32_LEAN_AND_MEAN
31 #endif
32 #include <windows.h>
33 #include <stdlib.h>
34
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 *));
38
39 /* To protect the thread/key association data structure modifications. */
40 static CRITICAL_SECTION __mingwthr_cs;
41 static volatile int __mingwthr_cs_init = 0;
42
43 typedef struct __mingwthr_key __mingwthr_key_t;
44
45 /* The list of threads active with key/dtor pairs. */
46 struct __mingwthr_key {
47   DWORD key;
48   void (*dtor)(void *);
49   __mingwthr_key_t volatile *next;
50 };
51
52
53 static __mingwthr_key_t volatile *key_dtor_list;
54
55 int
56 ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *))
57 {
58   __mingwthr_key_t *new_key;
59
60   if (__mingwthr_cs_init == 0)
61     return 0;
62   new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
63   if (new_key == NULL)
64     return -1;
65
66   new_key->key = key;
67   new_key->dtor = dtor;
68
69   EnterCriticalSection (&__mingwthr_cs);
70
71   new_key->next = key_dtor_list;
72   key_dtor_list = new_key;
73
74   LeaveCriticalSection (&__mingwthr_cs);
75   return 0;
76 }
77
78 int
79 ___w64_mingwthr_remove_key_dtor (DWORD key)
80 {
81   __mingwthr_key_t volatile *prev_key;
82   __mingwthr_key_t volatile *cur_key;
83
84   if (__mingwthr_cs_init == 0)
85     return 0;
86
87   EnterCriticalSection (&__mingwthr_cs);
88
89   prev_key = NULL;
90   cur_key = key_dtor_list;
91
92   while (cur_key != NULL)
93     {
94       if ( cur_key->key == key)
95         {
96           if (prev_key == NULL)
97             key_dtor_list = cur_key->next;
98           else
99             prev_key->next = cur_key->next;
100
101           free ((void*)cur_key);
102           break;
103         }
104       prev_key = cur_key;
105       cur_key = cur_key->next;
106     }
107
108   LeaveCriticalSection (&__mingwthr_cs);
109   return 0;
110 }
111
112 static void
113 __mingwthr_run_key_dtors (void)
114 {
115   __mingwthr_key_t volatile *keyp;
116
117   if (__mingwthr_cs_init == 0)
118     return;
119   EnterCriticalSection (&__mingwthr_cs);
120
121   for (keyp = key_dtor_list; keyp; )
122     {
123       LPVOID value = TlsGetValue (keyp->key);
124       if (GetLastError () == ERROR_SUCCESS)
125         {
126           if (value)
127             (*keyp->dtor) (value);
128         }
129       keyp = keyp->next;
130     }
131
132   LeaveCriticalSection (&__mingwthr_cs);
133 }
134
135 WINBOOL
136 __mingw_TLScallback (HANDLE hDllHandle __attribute__ ((__unused__)),
137                      DWORD reason,
138                      LPVOID reserved __attribute__ ((__unused__)))
139 {
140   switch (reason)
141     {
142     case DLL_PROCESS_ATTACH:
143       if (__mingwthr_cs_init == 0)
144         InitializeCriticalSection (&__mingwthr_cs);
145       __mingwthr_cs_init = 1;
146       break;
147     case DLL_PROCESS_DETACH:
148       __mingwthr_run_key_dtors();
149       if (__mingwthr_cs_init == 1)
150         {
151           __mingwthr_cs_init = 0;
152           DeleteCriticalSection (&__mingwthr_cs);
153         }
154       break;
155     case DLL_THREAD_ATTACH:
156       break;
157     case DLL_THREAD_DETACH:
158       __mingwthr_run_key_dtors();
159       break;
160     }
161   return TRUE;
162 }