X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/blobdiff_plain/bf336dc52970daa394d119b11284a1b5016a74c0..1402a14592dde378698373044afbcef9c38ec2c2:/src/thread-w32.h diff --git a/src/thread-w32.h b/src/thread-w32.h index 181ebfc..393f0de 100644 --- a/src/thread-w32.h +++ b/src/thread-w32.h @@ -33,7 +33,7 @@ #define WIN32_LEAN_AND_MEAN #include -static DWORD tls_key; +static DWORD tls_key = TLS_OUT_OF_INDEXES; #define tls_key_valid (tls_key != TLS_OUT_OF_INDEXES) static void init_once_cb(void); @@ -158,3 +158,37 @@ static int init_once(void) return 1; } + +#if !TEST_W32_NO_DLLMAIN + +/* + * On Windows, DLLs are notified of thread exit via the DllMain entry point. + * This works in all versions. + */ +#if !DLL_EXPORT +static +#endif +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID p) +{ + if (reason == DLL_THREAD_DETACH && tls_key != TLS_OUT_OF_INDEXES) + free(TlsGetValue(tls_key)); + + return TRUE; +} + +/* + * We can achieve similar behaviour with static linking executables by + * putting a pointer to the entry point in a special section. + * + * I believe this is supported beginning around Windows XP. + */ +#if !DLL_EXPORT +#pragma data_seg(".CRT$XLF") +#if __GNUC__ +__attribute__((section(".CRT$XLF"))) +#endif +PIMAGE_TLS_CALLBACK cdecl__tls_hook = (PIMAGE_TLS_CALLBACK)DllMain; +#pragma data_seg() +#endif + +#endif