diff options
Diffstat (limited to 'misc/win32/start.c')
-rw-r--r-- | misc/win32/start.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/misc/win32/start.c b/misc/win32/start.c index e15bf5d83..cab9da55e 100644 --- a/misc/win32/start.c +++ b/misc/win32/start.c @@ -18,11 +18,13 @@ #include "apr_general.h" #include "apr_pools.h" #include "apr_signal.h" +#include "apr_hash.h" #include "ShellAPI.h" #include "apr_arch_misc.h" /* for WSAHighByte / WSALowByte */ #include "wchar.h" #include "apr_arch_file_io.h" +#include "apr_arch_threadproc.h" #include "assert.h" /* This symbol is _private_, although it must be exported. @@ -187,6 +189,11 @@ APR_DECLARE(apr_status_t) apr_initialize(void) apr_pool_tag(pool, "apr_initialize"); +#if defined(APR_DECLARE_EXPORT) + /* Initialize threadpriv table */ + apr_tls_threadkeys = apr_hash_make(pool); +#endif + iVersionRequested = MAKEWORD(WSAHighByte, WSALowByte); err = WSAStartup((WORD) iVersionRequested, &wsaData); if (err) { @@ -203,12 +210,63 @@ APR_DECLARE(apr_status_t) apr_initialize(void) return APR_SUCCESS; } +#if defined(APR_DECLARE_EXPORT) +typedef (apr_thredkey_destfn_t)(void *data); + +static void threadkey_terminate() +{ + apr_hash_index_t *hi = apr_hash_first(NULL, apr_tls_threadkeys); + + for (; hi != NULL; hi = apr_hash_next(hi)) { + LPDWORD key; + apr_hash_this(hi, &key, NULL, NULL); + TlsFree(*key); + } +} + +static void threadkey_detach() +{ + apr_hash_index_t *hi = apr_hash_first(NULL, apr_tls_threadkeys); + + for (; hi != NULL; hi = apr_hash_next(hi)) { + apr_thredkey_destfn_t *dest = NULL; + LPDWORD key; + void *data; + apr_hash_this(hi, &key, NULL, (void **)&dest); + data = TlsGetValue(*key); + (*dest)(data); + } +} + +BOOL APIENTRY DllMain(HINSTANCE instance, + DWORD reason_for_call, + LPVOID lpReserved) +{ + switch (reason_for_call) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + threadkey_detach(); + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + +#endif /* APR_DECLARE_EXPORT */ + APR_DECLARE_NONSTD(void) apr_terminate(void) { initialized--; if (initialized) { return; } +#if defined(APR_DECLARE_EXPORT) + threadkey_terminate(); +#endif apr_pool_terminate(); WSACleanup(); |