summaryrefslogtreecommitdiff
path: root/include/arch
diff options
context:
space:
mode:
authorIvan Zhakov <ivan@apache.org>2019-12-14 10:45:39 +0000
committerIvan Zhakov <ivan@apache.org>2019-12-14 10:45:39 +0000
commitc90021a5071ba646356fb1509a0cdff7416653b4 (patch)
tree2e4a61716deed375963fb907e7da61eea5499890 /include/arch
parentd5f961e6c40af43e0a3e1edf3005a661edb38075 (diff)
downloadapr-c90021a5071ba646356fb1509a0cdff7416653b4.tar.gz
win32: Rewrite late linking code (again) without using INIT_ONCE as groundwork
to backport r1866562 and 1859477 to APR 1.6.x and APR 1.7.x. It also slightly improves performance and reduce lock contention. * include/arch/win32/apr_arch_misc.h (apr_winapi_fpt_##fn): Declare as volatile and initialize to (ULONG_PTR) -1. (apr_winapi_ctrl_##fn, apr_winapi_init_once_##fn): Remove. (apr_winapi_ld_##fn): Concurrently invoke apr_load_dll_func() if apr_winapi_fpt_##fn == -1. * misc/win32/misc.c (win32_late_dll_t.control): Remove. (win32_late_dll_t.dll_handle): Declare as volatile. (late_dll): Initialize dll_handle to INVALID_HANDLE_VALUE (assume that is invalid module handle). (apr_load_dll_func): Concurrently load library if dll_handle == INVALID_HANDLE_VALUE. Then perform CAS and then free library if other thread performed initialization before. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1871447 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'include/arch')
-rw-r--r--include/arch/win32/apr_arch_misc.h23
1 files changed, 9 insertions, 14 deletions
diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h
index 196914e68..387ea79f5 100644
--- a/include/arch/win32/apr_arch_misc.h
+++ b/include/arch/win32/apr_arch_misc.h
@@ -201,20 +201,15 @@ FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char *fnName, int ordinal);
*/
#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; \