win32: Use INIT_ONCE to prevent loading delayed libraries multiple times.

git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1859477 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/misc/win32/misc.c b/misc/win32/misc.c
index ff9c076..b6ee202 100644
--- a/misc/win32/misc.c
+++ b/misc/win32/misc.c
@@ -139,39 +139,52 @@
  */
 
 typedef struct win32_late_dll_t {
+    INIT_ONCE control;
     const apr_wchar_t *dll_name;
     HMODULE dll_handle;
 } win32_late_dll_t;
 
 static win32_late_dll_t late_dll[DLL_defined] = {
-    {L"kernel32", NULL},
-    {L"advapi32", NULL},
-    {L"mswsock", NULL},
-    {L"ws2_32", NULL},
-    {L"shell32", NULL},
-    {L"ntdll.dll", NULL},
-    {L"Iphplapi", NULL}
+    {INIT_ONCE_STATIC_INIT, L"kernel32", NULL},
+    {INIT_ONCE_STATIC_INIT, L"advapi32", NULL},
+    {INIT_ONCE_STATIC_INIT, L"mswsock", NULL},
+    {INIT_ONCE_STATIC_INIT, L"ws2_32", NULL},
+    {INIT_ONCE_STATIC_INIT, L"shell32", NULL},
+    {INIT_ONCE_STATIC_INIT, L"ntdll.dll", NULL},
+    {INIT_ONCE_STATIC_INIT, L"Iphplapi", NULL}
 };
 
+static BOOL WINAPI load_dll_callback(PINIT_ONCE InitOnce,
+                                     PVOID Parameter,
+                                     PVOID *Context)
+{
+    win32_late_dll_t *dll = Parameter;
+
+    dll->dll_handle = LoadLibraryW(dll->dll_name);
+
+    return TRUE;
+}
+
 FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
 {
-    if (!late_dll[fnLib].dll_handle) {
-        late_dll[fnLib].dll_handle = LoadLibraryW(late_dll[fnLib].dll_name);
-        if (!late_dll[fnLib].dll_handle)
-            return NULL;
-    }
+    win32_late_dll_t *dll = &late_dll[fnLib];
+
+    InitOnceExecuteOnce(&dll->control, load_dll_callback, dll, NULL);
+    if (!dll->dll_handle)
+        return NULL;
+
 #if defined(_WIN32_WCE)
     if (ordinal)
-        return GetProcAddressA(late_dll[fnLib].dll_handle,
+        return GetProcAddressA(dll->dll_handle,
                                (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddressA(late_dll[fnLib].dll_handle, fnName);
+        return GetProcAddressA(dll->dll_handle, fnName);
 #else
     if (ordinal)
-        return GetProcAddress(late_dll[fnLib].dll_handle,
+        return GetProcAddress(dll->dll_handle,
                               (const char *) (apr_ssize_t)ordinal);
     else
-        return GetProcAddress(late_dll[fnLib].dll_handle, fnName);
+        return GetProcAddress(dll->dll_handle, fnName);
 #endif
 }