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.PD 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 #include <stdarg.h> 20 #include <windef.h> 21 #include <winbase.h> 22 23 WINBOOL __mingw_TLScallback (HANDLE hDllHandle, DWORD reason, LPVOID reserved); 24 int ___w64_mingwthr_remove_key_dtor (DWORD key); 25 int ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *)); 26 27 /* To protect the thread/key association data structure modifications. */ 28 static CRITICAL_SECTION __mingwthr_cs; 29 static volatile int __mingwthr_cs_init = 0; 30 31 typedef struct __mingwthr_key __mingwthr_key_t; 32 33 /* The list of threads active with key/dtor pairs. */ 34 struct __mingwthr_key { 35 DWORD key; 36 void (*dtor)(void *); 37 __mingwthr_key_t volatile *next; 38 }; 39 40 41 static __mingwthr_key_t volatile *key_dtor_list; 42 43 int 44 ___w64_mingwthr_add_key_dtor (DWORD key, void (*dtor)(void *)) 45 { 46 __mingwthr_key_t *new_key; 47 48 if (__mingwthr_cs_init == 0) 49 return 0; 50 new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t)); 51 if (new_key == NULL) 52 return -1; 53 54 new_key->key = key; 55 new_key->dtor = dtor; 56 57 EnterCriticalSection (&__mingwthr_cs); 58 59 new_key->next = key_dtor_list; 60 key_dtor_list = new_key; 61 62 LeaveCriticalSection (&__mingwthr_cs); 63 return 0; 64 } 65 66 int 67 ___w64_mingwthr_remove_key_dtor (DWORD key) 68 { 69 __mingwthr_key_t volatile *prev_key; 70 __mingwthr_key_t volatile *cur_key; 71 72 if (__mingwthr_cs_init == 0) 73 return 0; 74 75 EnterCriticalSection (&__mingwthr_cs); 76 77 prev_key = NULL; 78 cur_key = key_dtor_list; 79 80 while (cur_key != NULL) 81 { 82 if ( cur_key->key == key) 83 { 84 if (prev_key == NULL) 85 key_dtor_list = cur_key->next; 86 else 87 prev_key->next = cur_key->next; 88 89 free ((void*)cur_key); 90 break; 91 } 92 prev_key = cur_key; 93 cur_key = cur_key->next; 94 } 95 96 LeaveCriticalSection (&__mingwthr_cs); 97 return 0; 98 } 99 100 static void 101 __mingwthr_run_key_dtors (void) 102 { 103 __mingwthr_key_t volatile *keyp; 104 105 if (__mingwthr_cs_init == 0) 106 return; 107 EnterCriticalSection (&__mingwthr_cs); 108 109 for (keyp = key_dtor_list; keyp; ) 110 { 111 LPVOID value = TlsGetValue (keyp->key); 112 if (GetLastError () == ERROR_SUCCESS) 113 { 114 if (value) 115 (*keyp->dtor) (value); 116 } 117 keyp = keyp->next; 118 } 119 120 LeaveCriticalSection (&__mingwthr_cs); 121 } 122 123 WINBOOL 124 __mingw_TLScallback (HANDLE __UNUSED_PARAM(hDllHandle), 125 DWORD reason, 126 LPVOID __UNUSED_PARAM(reserved)) 127 { 128 switch (reason) 129 { 130 case DLL_PROCESS_ATTACH: 131 if (__mingwthr_cs_init == 0) 132 InitializeCriticalSection (&__mingwthr_cs); 133 __mingwthr_cs_init = 1; 134 break; 135 case DLL_PROCESS_DETACH: 136 __mingwthr_run_key_dtors(); 137 if (__mingwthr_cs_init == 1) 138 { 139 __mingwthr_cs_init = 0; 140 DeleteCriticalSection (&__mingwthr_cs); 141 } 142 break; 143 case DLL_THREAD_ATTACH: 144 break; 145 case DLL_THREAD_DETACH: 146 __mingwthr_run_key_dtors(); 147 break; 148 } 149 return TRUE; 150 } 151 152