]> pd.if.org Git - pdclib/blob - platform/win32/functions/threads/tss_create.c
PDCLib includes with quotes, not <>.
[pdclib] / platform / win32 / functions / threads / tss_create.c
1 #ifndef REGTEST\r
2 #include <threads.h>\r
3 #include <stdbool.h>\r
4 #include <windows.h>\r
5 \r
6 /* Pull in TLS support */\r
7 extern char _tls_used[];\r
8 \r
9 struct _PDCLIB_tss * _PDCLIB_tss_first = NULL;\r
10 \r
11 int tss_create( tss_t *key, tss_dtor_t dtor )\r
12 {\r
13     *key = malloc( sizeof *key );\r
14     if( !*key ) {\r
15         return thrd_nomem;\r
16     }\r
17 \r
18     (*key)->_Key = TlsAlloc();\r
19     if((*key)->_Key == TLS_OUT_OF_INDEXES) {\r
20         return thrd_error;\r
21     }\r
22     (*key)->_Destructor = dtor;\r
23     (*key)->_Next = _PDCLIB_tss_first;\r
24 \r
25     // TODO: make this atomic (& validate no other TLS blocks have been \r
26     // simultaneously allocated)\r
27     _PDCLIB_tss_first = *key;\r
28 \r
29     return thrd_success;\r
30 }\r
31 \r
32 static void NTAPI runTlsDestructors( void * image, DWORD reason, PVOID pv )\r
33 {\r
34     if( reason == DLL_THREAD_DETACH ) {\r
35         for(unsigned i = 0; i < TSS_DTOR_ITERATIONS; i++) {\r
36             struct _PDCLIB_tss * tss = _PDCLIB_tss_first;\r
37             bool destructorsRan = false;\r
38             while( tss ) {\r
39                 void * val = TlsGetValue( tss->_Key );\r
40                 if( val ) {\r
41                     TlsSetValue( tss->_Key, NULL );\r
42                     if( tss->_Destructor ) {\r
43                         tss->_Destructor( val );\r
44                         destructorsRan = true;\r
45                     }\r
46                 }\r
47 \r
48                 tss = tss->_Next;\r
49             }\r
50             if(!destructorsRan) break;\r
51         }\r
52     }\r
53 }\r
54 \r
55 #ifdef __GNUC__\r
56 __attribute__((__section__(".CRT$XLC")))\r
57 #else\r
58 __declspec(allocate(".CRT$XLC")) \r
59 #endif\r
60 PIMAGE_TLS_CALLBACK _PDCLIB_runTlsDestructors = runTlsDestructors;\r
61 \r
62 #endif\r
63 \r
64 #ifdef TEST\r
65 #include "_PDCLIB_test.h"\r
66 \r
67 /* Tested in tss_get.c */\r
68 int main( void )\r
69 {\r
70     return TEST_RESULTS;\r
71 }\r
72 \r
73 #endif