diff options
author | Mladen Turk <mturk@apache.org> | 2006-08-24 07:24:35 +0000 |
---|---|---|
committer | Mladen Turk <mturk@apache.org> | 2006-08-24 07:24:35 +0000 |
commit | 18a3c7249f9ccb2cdca924cdb0c30476cb7b425f (patch) | |
tree | ea28d33dd2f541e83cb07550447ccb53dc21c840 | |
parent | e5d401a4175aef217cf182797dfcc7d8a79420d7 (diff) | |
download | apr-18a3c7249f9ccb2cdca924cdb0c30476cb7b425f.tar.gz |
Implement apr_threadkey_private destructors on WIN32
instead silently ignoring them.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@434327 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | include/arch/win32/apr_arch_threadproc.h | 6 | ||||
-rw-r--r-- | misc/win32/start.c | 58 | ||||
-rw-r--r-- | threadproc/win32/threadpriv.c | 17 |
4 files changed, 83 insertions, 2 deletions
@@ -1,5 +1,9 @@ Changes for APR 1.3.0 + *) Implement apr_threadkey_private destructors on WIN32 + instead silently ignoring them, so that they behave like on + the pthreads powered platforms. [Mladen Turk] + *) Support MinGW. [John Vandenberg, Justin Erenkrantz] *) Implement apr_thread_yield on Unix in terms of pthread_yield or diff --git a/include/arch/win32/apr_arch_threadproc.h b/include/arch/win32/apr_arch_threadproc.h index 7af8ab686..d4d70d5c9 100644 --- a/include/arch/win32/apr_arch_threadproc.h +++ b/include/arch/win32/apr_arch_threadproc.h @@ -17,6 +17,7 @@ #include "apr_private.h" #include "apr_thread_proc.h" #include "apr_file_io.h" +#include "apr_hash.h" #ifndef THREAD_PROC_H #define THREAD_PROC_H @@ -68,5 +69,10 @@ struct apr_thread_once_t { long value; }; +#if defined(APR_DECLARE_EXPORT) +/* Provide to win32/start.c */ +extern apr_hash_t *apr_tls_threadkeys; +#endif + #endif /* ! THREAD_PROC_H */ 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(); diff --git a/threadproc/win32/threadpriv.c b/threadproc/win32/threadpriv.c index 0cbfe620e..b1001e107 100644 --- a/threadproc/win32/threadpriv.c +++ b/threadproc/win32/threadpriv.c @@ -16,11 +16,16 @@ #include "apr_arch_threadproc.h" #include "apr_thread_proc.h" +#include "apr_hash.h" #include "apr_general.h" #include "apr_lib.h" #include "apr_errno.h" #include "apr_portable.h" +#if defined(APR_DECLARE_EXPORT) +apr_hash_t *apr_tls_threadkeys = NULL; +#endif + APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, void (*dest)(void *), apr_pool_t *pool) @@ -33,6 +38,10 @@ APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key, (*key)->pool = pool; if (((*key)->key = TlsAlloc()) != 0xFFFFFFFF) { +#if defined(APR_DECLARE_EXPORT) + apr_hash_set(apr_tls_threadkeys, &((*key)->key), + sizeof(DWORD), dest); +#endif return APR_SUCCESS; } return apr_get_os_error(); @@ -59,7 +68,11 @@ APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key) { if (TlsFree(key->key)) { - return APR_SUCCESS; +#if defined(APR_DECLARE_EXPORT) + apr_hash_set(apr_tls_threadkeys, &(key->key), + sizeof(DWORD), NULL); +#endif + return APR_SUCCESS; } return apr_get_os_error(); } @@ -97,5 +110,5 @@ APR_DECLARE(apr_status_t) apr_os_threadkey_put(apr_threadkey_t **key, } (*key)->key = *thekey; return APR_SUCCESS; -} +} |