From fc41cd64d1dd86e65b729ddf28e9519e58491fad Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Tue, 12 Jun 2018 17:05:25 +0300 Subject: [PATCH] mdbx: add MDBX_CONFIG_MANUAL_TLS_CALLBACK. Change-Id: I3ed60348f532cc9206f9ec0e7c1d3428b4f037a2 --- mdbx.h | 15 +++++++++++++++ src/lck-windows.c | 41 ++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/mdbx.h b/mdbx.h index 9758fe57..a02e4254 100644 --- a/mdbx.h +++ b/mdbx.h @@ -203,6 +203,21 @@ typedef struct mdbx_build_info { extern LIBMDBX_API const mdbx_version_info mdbx_version; extern LIBMDBX_API const mdbx_build_info mdbx_build; +#if defined(_WIN32) || defined(_WIN64) +/* Dll initialization callback for old Windows NT versions. This function MUST + * be called once from DllMain() for each reason (DLL_PROCESS_ATTACH, + * DLL_PROCESS_DETACH, DLL_THREAD_ATTACH and DLL_THREAD_DETACH). Do this + * carefully and ONLY when actual Windows version don't support initialization + * via "TLS Directory" (e.g .CRT$XL[A-Z] sections in executable or dll file). */ +#ifndef MDBX_CONFIG_MANUAL_TLS_CALLBACK +#define MDBX_CONFIG_MANUAL_TLS_CALLBACK 0 +#endif +#if MDBX_CONFIG_MANUAL_TLS_CALLBACK +void LIBMDBX_API NTAPI mdbx_dll_callback(PVOID module, DWORD reason, + PVOID reserved); +#endif /* MDBX_CONFIG_MANUAL_TLS_CALLBACK */ +#endif /* Windows */ + /* The name of the lock file in the DB environment */ #define MDBX_LOCKNAME "/mdbx.lck" /* The name of the data file in the DB environment */ diff --git a/src/lck-windows.c b/src/lck-windows.c index cb5add9b..24afcaac 100644 --- a/src/lck-windows.c +++ b/src/lck-windows.c @@ -24,13 +24,17 @@ * LY */ -/*----------------------------------------------------------------------------*/ -/* rthc */ +static void mdbx_winnt_import(void); -static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { +#if !MDBX_CONFIG_MANUAL_TLS_CALLBACK +static +#endif /* !MDBX_CONFIG_MANUAL_TLS_CALLBACK */ + void NTAPI + mdbx_dll_callback(PVOID module, DWORD reason, PVOID reserved) { (void)reserved; switch (reason) { case DLL_PROCESS_ATTACH: + mdbx_winnt_import(); mdbx_rthc_global_init(); break; case DLL_PROCESS_DETACH: @@ -45,6 +49,7 @@ static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { } } +#if !MDBX_CONFIG_MANUAL_TLS_CALLBACK /* *INDENT-OFF* */ /* clang-format off */ #if defined(_MSC_VER) @@ -55,7 +60,7 @@ static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { /* kick a linker to create the TLS directory if not already done */ # pragma comment(linker, "/INCLUDE:_tls_used") /* Force some symbol references. */ -# pragma comment(linker, "/INCLUDE:mdbx_tls_callback") +# pragma comment(linker, "/INCLUDE:mdbx_tls_anchor") /* specific const-segment for WIN64 */ # pragma const_seg(".CRT$XLB") const @@ -63,12 +68,12 @@ static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { /* kick a linker to create the TLS directory if not already done */ # pragma comment(linker, "/INCLUDE:__tls_used") /* Force some symbol references. */ -# pragma comment(linker, "/INCLUDE:_mdbx_tls_callback") +# pragma comment(linker, "/INCLUDE:_mdbx_tls_anchor") /* specific data-segment for WIN32 */ # pragma data_seg(".CRT$XLB") # endif - PIMAGE_TLS_CALLBACK mdbx_tls_callback = tls_callback; + __declspec(allocate(".CRT$XLB")) PIMAGE_TLS_CALLBACK mdbx_tls_anchor = mdbx_dll_callback; # pragma data_seg(pop) # pragma const_seg(pop) @@ -76,13 +81,13 @@ static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) { # ifdef _WIN64 const # endif - PIMAGE_TLS_CALLBACK mdbx_tls_callback __attribute__((section(".CRT$XLB"), used)) - = tls_callback; + PIMAGE_TLS_CALLBACK mdbx_tls_anchor __attribute__((section(".CRT$XLB"), used)) = mdbx_dll_callback; #else # error FIXME #endif /* *INDENT-ON* */ /* clang-format on */ +#endif /* !MDBX_CONFIG_MANUAL_TLS_CALLBACK */ /*----------------------------------------------------------------------------*/ @@ -643,11 +648,18 @@ static void WINAPI stub_srwlock_ReleaseExclusive(MDBX_srwlock *srwl) { srwl->writerCount = 0; } -static void WINAPI srwlock_thunk_init(MDBX_srwlock *srwl) { +MDBX_srwlock_function mdbx_srwlock_Init, mdbx_srwlock_AcquireShared, + mdbx_srwlock_ReleaseShared, mdbx_srwlock_AcquireExclusive, + mdbx_srwlock_ReleaseExclusive; + +/*----------------------------------------------------------------------------*/ + +static void mdbx_winnt_import(void) { HINSTANCE hInst = GetModuleHandleA("kernel32.dll"); MDBX_srwlock_function init = (MDBX_srwlock_function)GetProcAddress(hInst, "InitializeSRWLock"); if (init != NULL) { + mdbx_srwlock_Init = init; mdbx_srwlock_AcquireShared = (MDBX_srwlock_function)GetProcAddress(hInst, "AcquireSRWLockShared"); mdbx_srwlock_ReleaseShared = @@ -657,19 +669,10 @@ static void WINAPI srwlock_thunk_init(MDBX_srwlock *srwl) { mdbx_srwlock_ReleaseExclusive = (MDBX_srwlock_function)GetProcAddress(hInst, "ReleaseSRWLockExclusive"); } else { - init = stub_srwlock_Init; + mdbx_srwlock_Init = stub_srwlock_Init; mdbx_srwlock_AcquireShared = stub_srwlock_AcquireShared; mdbx_srwlock_ReleaseShared = stub_srwlock_ReleaseShared; mdbx_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive; mdbx_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive; } - mdbx_compiler_barrier(); - mdbx_srwlock_Init = init; - mdbx_srwlock_Init(srwl); } - -MDBX_srwlock_function mdbx_srwlock_Init = srwlock_thunk_init; -MDBX_srwlock_function mdbx_srwlock_AcquireShared; -MDBX_srwlock_function mdbx_srwlock_ReleaseShared; -MDBX_srwlock_function mdbx_srwlock_AcquireExclusive; -MDBX_srwlock_function mdbx_srwlock_ReleaseExclusive;