OSDN Git Service

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