From 31738ae89129625a647302a1c9a2a2b24a51f4e2 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 18 May 2019 19:58:02 +0000 Subject: win32: Use INIT_ONCE to prevent loading delayed libraries multiple times. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@1859477 13f79535-47bb-0310-9956-ffa450edef68 --- misc/win32/misc.c | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/misc/win32/misc.c b/misc/win32/misc.c index ff9c076ab..b6ee202b0 100644 --- a/misc/win32/misc.c +++ b/misc/win32/misc.c @@ -139,39 +139,52 @@ apr_status_t apr_get_oslevel(apr_oslevel_e *level) */ 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 } -- cgit v1.2.1