X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=platform%2Fwin32%2Ffunctions%2Fthreads%2Ftss_create.c;fp=platform%2Fwin32%2Ffunctions%2Fthreads%2Ftss_create.c;h=af6da3f69a71b5a2ce3b08d19b52ac1d82cd6d64;hb=639bad513ab9399ed9a8c588a476a10dbe6c9478;hp=0000000000000000000000000000000000000000;hpb=008908f7a61acf9df1248c005378a3c4b4393547;p=pdclib diff --git a/platform/win32/functions/threads/tss_create.c b/platform/win32/functions/threads/tss_create.c new file mode 100644 index 0000000..af6da3f --- /dev/null +++ b/platform/win32/functions/threads/tss_create.c @@ -0,0 +1,73 @@ +#ifndef REGTEST +#include +#include +#include + +/* Pull in TLS support */ +extern char _tls_used[]; + +struct _PDCLIB_tss * _PDCLIB_tss_first = NULL; + +int tss_create( tss_t *key, tss_dtor_t dtor ) +{ + *key = malloc( sizeof *key ); + if( !*key ) { + return thrd_nomem; + } + + (*key)->_Key = TlsAlloc(); + if((*key)->_Key == TLS_OUT_OF_INDEXES) { + return thrd_error; + } + (*key)->_Destructor = dtor; + (*key)->_Next = _PDCLIB_tss_first; + + // TODO: make this atomic (& validate no other TLS blocks have been + // simultaneously allocated) + _PDCLIB_tss_first = *key; + + return thrd_success; +} + +static void NTAPI runTlsDestructors( void * image, DWORD reason, PVOID pv ) +{ + if( reason == DLL_THREAD_DETACH ) { + for(unsigned i = 0; i < TSS_DTOR_ITERATIONS; i++) { + struct _PDCLIB_tss * tss = _PDCLIB_tss_first; + bool destructorsRan = false; + while( tss ) { + void * val = TlsGetValue( tss->_Key ); + if( val ) { + TlsSetValue( tss->_Key, NULL ); + if( tss->_Destructor ) { + tss->_Destructor( val ); + destructorsRan = true; + } + } + + tss = tss->_Next; + } + if(!destructorsRan) break; + } + } +} + +#ifdef __GNUC__ +__attribute__((__section__(".CRT$XLC"))) +#else +__declspec(allocate(".CRT$XLC")) +#endif +PIMAGE_TLS_CALLBACK _PDCLIB_runTlsDestructors = runTlsDestructors; + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +/* Tested in tss_get.c */ +int main( void ) +{ + return TEST_RESULTS; +} + +#endif \ No newline at end of file