[prev in list] [next in list] [prev in thread] [next in thread] 

List:       apr-cvs
Subject:    svn commit: r1916420 - in /apr/apr/branches/1.7.x: ./ include/arch/win32/apr_arch_misc.h misc/win32/
From:       ivan () apache ! org
Date:       2024-03-19 13:22:14
Message-ID: 20240319132214.56E3D17AF51 () svn01-us-east ! apache ! org
[Download RAW message or body]

Author: ivan
Date: Tue Mar 19 13:22:13 2024
New Revision: 1916420

URL: http://svn.apache.org/viewvc?rev=1916420&view=rev
Log:
On 1.7.x: Merge r1916254, r1916255, r1916256, r1916257, r1916258 from trunk:
  Fixes and improvements for win32 DLL late linking code.

Modified:
    apr/apr/branches/1.7.x/   (props changed)
    apr/apr/branches/1.7.x/include/arch/win32/apr_arch_misc.h
    apr/apr/branches/1.7.x/misc/win32/misc.c

Propchange: apr/apr/branches/1.7.x/
------------------------------------------------------------------------------
  Merged /apr/apr/branches/1.7.x-r1871447:r1916253-1916419

Modified: apr/apr/branches/1.7.x/include/arch/win32/apr_arch_misc.h
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.7.x/include/arch/win32/apr_arch_misc.h?rev=1916420&r1=1916419&r2=1916420&view=diff
 ==============================================================================
--- apr/apr/branches/1.7.x/include/arch/win32/apr_arch_misc.h (original)
+++ apr/apr/branches/1.7.x/include/arch/win32/apr_arch_misc.h Tue Mar 19 13:22:13 \
2024 @@ -198,15 +198,16 @@ 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 int apr_winapi_chk_##fn = 0; \
+    static volatile apr_winapi_fpt_##fn apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
(ULONG_PTR) (-1); \  static APR_INLINE int apr_winapi_ld_##fn(void) \
-    {   if (apr_winapi_pfn_##fn) return 1; \
-        if (apr_winapi_chk_##fn ++) return 0; \
-        if (!apr_winapi_pfn_##fn) \
-            apr_winapi_pfn_##fn = (apr_winapi_fpt_##fn) \
-                                      apr_load_dll_func(lib, #fn, ord); \
-        if (apr_winapi_pfn_##fn) return 1; else return 0; }; \
+    {   \
+        apr_winapi_fpt_##fn cached_func = apr_winapi_pfn_##fn; \
+        if (cached_func == (apr_winapi_fpt_##fn) (ULONG_PTR) (-1)) { \
+            cached_func = (apr_winapi_fpt_##fn) apr_load_dll_func(lib, #fn, ord); \
+            /* Pointer-sized writes are atomic on Windows. */ \
+            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/misc/win32/misc.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.7.x/misc/win32/misc.c?rev=1916420&r1=1916419&r2=1916420&view=diff
 ==============================================================================
--- apr/apr/branches/1.7.x/misc/win32/misc.c (original)
+++ apr/apr/branches/1.7.x/misc/win32/misc.c Tue Mar 19 13:22:13 2024
@@ -161,32 +161,61 @@ apr_status_t apr_get_oslevel(apr_oslevel
  * missing from one or more releases of the Win32 API
  */
 
-static const char* const lateDllName[DLL_defined] = {
-    "kernel32", "advapi32", "mswsock",  "ws2_32", "shell32", "ntdll.dll",
-    "Iphplapi"  };
-static HMODULE lateDllHandle[DLL_defined] = {
-     NULL,       NULL,       NULL,       NULL,     NULL,      NULL,
-     NULL       };
+typedef struct win32_late_dll_t {
+    const char *dll_name;
+    volatile HMODULE dll_handle;
+} win32_late_dll_t;
+
+static win32_late_dll_t late_dll[DLL_defined] = {
+    {"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}
+};
 
 FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
 {
-    if (!lateDllHandle[fnLib]) { 
-        lateDllHandle[fnLib] = LoadLibraryA(lateDllName[fnLib]);
-        if (!lateDllHandle[fnLib])
-            return NULL;
+    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);
+        }
     }
+
+    if (!cached_dll_handle) {
+        return NULL;
+    }
+
 #if defined(_WIN32_WCE)
     if (ordinal)
-        return GetProcAddressA(lateDllHandle[fnLib], (const char *)
-                                                     (apr_ssize_t)ordinal);
+        return GetProcAddressA(cached_dll_handle,
+                               (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddressA(lateDllHandle[fnLib], fnName);
+        return GetProcAddressA(cached_dll_handle, fnName);
 #else
     if (ordinal)
-        return GetProcAddress(lateDllHandle[fnLib], (const char *)
-                                                    (apr_ssize_t)ordinal);
+        return GetProcAddress(cached_dll_handle,
+                              (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddress(lateDllHandle[fnLib], fnName);
+        return GetProcAddress(cached_dll_handle, fnName);
 #endif
 }
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic