You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by iv...@apache.org on 2024/03/12 14:21:41 UTC

svn commit: r1916257 - in /apr/apr/branches/1.7.x-r1871447: include/arch/win32/apr_arch_misc.h misc/win32/misc.c

Author: ivan
Date: Tue Mar 12 14:21:40 2024
New Revision: 1916257

URL: http://svn.apache.org/viewvc?rev=1916257&view=rev
Log:
On 1.7.x-r1871447 branch:
  Merge r1871447 from trunk.

Modified:
    apr/apr/branches/1.7.x-r1871447/include/arch/win32/apr_arch_misc.h
    apr/apr/branches/1.7.x-r1871447/misc/win32/misc.c

Modified: apr/apr/branches/1.7.x-r1871447/include/arch/win32/apr_arch_misc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.7.x-r1871447/include/arch/win32/apr_arch_misc.h?rev=1916257&r1=1916256&r2=1916257&view=diff
==============================================================================
--- apr/apr/branches/1.7.x-r1871447/include/arch/win32/apr_arch_misc.h (original)
+++ apr/apr/branches/1.7.x-r1871447/include/arch/win32/apr_arch_misc.h Tue Mar 12 14:21:40 2024
@@ -198,20 +198,15 @@ FARPROC apr_load_dll_func(apr_dlltoken_e
  */
 #define APR_DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \
     typedef rettype (calltype *apr_winapi_fpt_##fn) args; \
-    static apr_winapi_fpt_##fn apr_winapi_pfn_##fn = NULL; \
-    static INIT_ONCE apr_winapi_ctrl_##fn = {INIT_ONCE_STATIC_INIT}; \
-    static BOOL WINAPI apr_winapi_init_once_##fn(PINIT_ONCE init_once,\
-                                                 PVOID baton, PVOID *context) \
-    { \
-        apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
-            apr_load_dll_func(lib, #fn, ord); \
-        return TRUE; \
-    } \
-static APR_INLINE int apr_winapi_ld_##fn(void) \
-    {   if (apr_winapi_pfn_##fn) return 1; \
-        InitOnceExecuteOnce(&apr_winapi_ctrl_##fn, apr_winapi_init_once_##fn, \
-                            NULL, NULL); \
-        if (apr_winapi_pfn_##fn) return 1; else return 0; }; \
+    static volatile apr_winapi_fpt_##fn apr_winapi_pfn_##fn = (PVOID) (ULONG_PTR) (-1); \
+    static APR_INLINE int apr_winapi_ld_##fn(void) \
+    {   \
+        apr_winapi_fpt_##fn cached_func = apr_winapi_pfn_##fn; \
+        if (cached_func == (PVOID) (ULONG_PTR) (-1)) { \
+            cached_func = (apr_winapi_fpt_##fn) apr_load_dll_func(lib, #fn, ord); \
+            InterlockedExchangePointer(&((PVOID)apr_winapi_pfn_##fn), cached_func); \
+        } \
+        if (cached_func) return 1; else return 0; }; \
     static APR_INLINE rettype apr_winapi_##fn args \
     {   if (apr_winapi_ld_##fn()) \
             return (*(apr_winapi_pfn_##fn)) names; \

Modified: apr/apr/branches/1.7.x-r1871447/misc/win32/misc.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.7.x-r1871447/misc/win32/misc.c?rev=1916257&r1=1916256&r2=1916257&view=diff
==============================================================================
--- apr/apr/branches/1.7.x-r1871447/misc/win32/misc.c (original)
+++ apr/apr/branches/1.7.x-r1871447/misc/win32/misc.c Tue Mar 12 14:21:40 2024
@@ -162,52 +162,60 @@ apr_status_t apr_get_oslevel(apr_oslevel
  */
 
 typedef struct win32_late_dll_t {
-    INIT_ONCE control;
     const char *dll_name;
-    HMODULE dll_handle;
+    volatile HMODULE dll_handle;
 } win32_late_dll_t;
 
 static win32_late_dll_t late_dll[DLL_defined] = {
-    {INIT_ONCE_STATIC_INIT, "kernel32", NULL},
-    {INIT_ONCE_STATIC_INIT, "advapi32", NULL},
-    {INIT_ONCE_STATIC_INIT, "mswsock", NULL},
-    {INIT_ONCE_STATIC_INIT, "ws2_32", NULL},
-    {INIT_ONCE_STATIC_INIT, "shell32", NULL},
-    {INIT_ONCE_STATIC_INIT, "ntdll.dll", NULL},
-    {INIT_ONCE_STATIC_INIT, "Iphplapi", NULL}
+    {"kernel32", INVALID_HANDLE_VALUE},
+    {"advapi32", INVALID_HANDLE_VALUE},
+    {"mswsock", INVALID_HANDLE_VALUE},
+    {"ws2_32", INVALID_HANDLE_VALUE},
+    {"shell32", INVALID_HANDLE_VALUE},
+    {"ntdll.dll", INVALID_HANDLE_VALUE},
+    {"Iphplapi", INVALID_HANDLE_VALUE}
 };
 
-static BOOL WINAPI load_dll_callback(PINIT_ONCE InitOnce,
-                                     PVOID Parameter,
-                                     PVOID *Context)
-{
-    win32_late_dll_t *dll = Parameter;
-
-    dll->dll_handle = LoadLibrary(dll->dll_name);
-
-    return TRUE;
-}
-
 FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
 {
     win32_late_dll_t *dll = &late_dll[fnLib];
+    HMODULE cached_dll_handle;
+
+    /* Pointer sized reads are atomic on Windows. */
+    cached_dll_handle = dll->dll_handle;
+    if (cached_dll_handle == INVALID_HANDLE_VALUE) {
+        HMODULE dll_handle = NULL;
+
+        dll_handle = LoadLibrary(dll->dll_name);
+
+        cached_dll_handle = InterlockedCompareExchangePointer(&dll->dll_handle,
+                                                              dll_handle,
+                                                              INVALID_HANDLE_VALUE);
+        if (cached_dll_handle == INVALID_HANDLE_VALUE) {
+            cached_dll_handle = dll_handle;
+        }
+        else if (dll_handle) {
+            /* Other thread won the race: release our library handle. */
+            FreeLibrary(dll_handle);
+        }
+    }
 
-    InitOnceExecuteOnce(&dll->control, load_dll_callback, dll, NULL);
-    if (!dll->dll_handle)
+    if (!cached_dll_handle) {
         return NULL;
+    }
 
 #if defined(_WIN32_WCE)
     if (ordinal)
-        return GetProcAddressA(dll->dll_handle,
+        return GetProcAddressA(cached_dll_handle,
                                (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddressA(dll->dll_handle, fnName);
+        return GetProcAddressA(cached_dll_handle, fnName);
 #else
     if (ordinal)
-        return GetProcAddress(dll->dll_handle,
+        return GetProcAddress(cached_dll_handle,
                               (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddress(dll->dll_handle, fnName);
+        return GetProcAddress(cached_dll_handle, fnName);
 #endif
 }