diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-12 04:59:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-12 04:59:58 +0000 |
commit | cc13dc44324dd5970d7a239e243a38d5f22cf64f (patch) | |
tree | e7429020c9c6aec4b93a84dd63b810f67dacce9c /misc/win32 | |
parent | Adding debian version 1.7.2-3.2. (diff) | |
download | apr-cc13dc44324dd5970d7a239e243a38d5f22cf64f.tar.xz apr-cc13dc44324dd5970d7a239e243a38d5f22cf64f.zip |
Merging upstream version 1.7.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'misc/win32')
-rw-r--r-- | misc/win32/misc.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/misc/win32/misc.c b/misc/win32/misc.c index bfb7efa..807ad60 100644 --- a/misc/win32/misc.c +++ b/misc/win32/misc.c @@ -161,32 +161,61 @@ apr_status_t apr_get_oslevel(apr_oslevel_e *level) * 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 } |