Take 2 for the PATCH that uses hash table instead
fixed size struct.
This cause that init and terminate functions has been
moved to the apr_initialize/terminate because of
pool needed for construction table.

Comments?

--
Mladen.
Index: misc/win32/start.c
===================================================================
--- misc/win32/start.c  (revision 432623)
+++ misc/win32/start.c  (working copy)
@@ -18,6 +18,7 @@
 #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 */
@@ -126,7 +127,7 @@
         sysstr = GetEnvironmentStringsW();
         dupenv = warrsztoastr(&_environ, sysstr, -1);
 
-       if (env) {
+        if (env) {
             *env = apr_malloc_dbg((dupenv + 1) * sizeof (char *),
                                   __FILE__, __LINE__ );
             memcpy((void*)*env, _environ, (dupenv + 1) * sizeof (char *));
@@ -159,6 +160,9 @@
 /* Provide to win32/thread.c */
 extern DWORD tls_apr_thread;
 
+/* Provide to win32/threadpriv.c */
+extern apr_hash_t *tls_apr_threadkeys;
+
 APR_DECLARE(apr_status_t) apr_initialize(void)
 {
     apr_pool_t *pool;
@@ -186,6 +190,9 @@
     }
 
     apr_pool_tag(pool, "apr_initialize");
+    
+    /* Initialize threadpriv table */
+    tls_apr_threadkeys = apr_hash_make(pool);
 
     iVersionRequested = MAKEWORD(WSAHighByte, WSALowByte);
     err = WSAStartup((WORD) iVersionRequested, &wsaData);
@@ -203,12 +210,28 @@
     return APR_SUCCESS;
 }
 
+#if APR_DECLARE_EXPORT
+static void threadkey_terminate()
+{
+    apr_hash_index_t *hi = apr_hash_first(NULL, tls_apr_threadkeys);
+
+    for (; hi != NULL; hi = apr_hash_next(hi)) {
+        LPDWORD key;
+        apr_hash_this(hi, &key, NULL, NULL);
+        TlsFree(*key);
+    }
+}
+#endif
+
 APR_DECLARE_NONSTD(void) apr_terminate(void)
 {
     initialized--;
     if (initialized) {
         return;
     }
+#if APR_DECLARE_EXPORT
+    threadkey_terminate();
+#endif
     apr_pool_terminate();
     
     WSACleanup();
Index: threadproc/win32/threadpriv.c
===================================================================
--- threadproc/win32/threadpriv.c       (revision 432623)
+++ threadproc/win32/threadpriv.c       (working copy)
@@ -16,11 +16,50 @@
 
 #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"
 
+#ifdef APR_DECLARE_EXPORT
+apr_hash_t *tls_apr_threadkeys = NULL;
+
+typedef (apr_thredkey_destfn_t)(void *data);
+
+static void threadkey_detach()
+{
+    apr_hash_index_t *hi = apr_hash_first(NULL, tls_apr_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(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
                                                     void (*dest)(void *),
                                                     apr_pool_t *pool)
@@ -33,6 +72,10 @@
     (*key)->pool = pool;
 
     if (((*key)->key = TlsAlloc()) != 0xFFFFFFFF) {
+#ifdef APR_DECLARE_EXPORT
+        apr_hash_set(tls_apr_threadkeys, &((*key)->key),
+                     sizeof(DWORD), dest);
+#endif
         return APR_SUCCESS;
     }
     return apr_get_os_error();
@@ -59,7 +102,11 @@
 APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key)
 {
     if (TlsFree(key->key)) {
-        return APR_SUCCESS; 
+#ifdef APR_DECLARE_EXPORT
+        apr_hash_set(tls_apr_threadkeys, &(key->key),
+                     sizeof(DWORD), NULL);
+#endif
+        return APR_SUCCESS;
     }
     return apr_get_os_error();
 }
@@ -97,5 +144,5 @@
     }
     (*key)->key = *thekey;
     return APR_SUCCESS;
-}           
+}
 

Reply via email to