mdbx: add MDBX_CONFIG_MANUAL_TLS_CALLBACK.

Change-Id: I3ed60348f532cc9206f9ec0e7c1d3428b4f037a2
This commit is contained in:
Leonid Yuriev 2018-06-12 17:05:25 +03:00 committed by Leo Yuriev
parent 9f2bf6a377
commit fc41cd64d1
2 changed files with 37 additions and 19 deletions

15
mdbx.h
View File

@ -203,6 +203,21 @@ typedef struct mdbx_build_info {
extern LIBMDBX_API const mdbx_version_info mdbx_version; extern LIBMDBX_API const mdbx_version_info mdbx_version;
extern LIBMDBX_API const mdbx_build_info mdbx_build; 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 */ /* The name of the lock file in the DB environment */
#define MDBX_LOCKNAME "/mdbx.lck" #define MDBX_LOCKNAME "/mdbx.lck"
/* The name of the data file in the DB environment */ /* The name of the data file in the DB environment */

View File

@ -24,13 +24,17 @@
* LY * LY
*/ */
/*----------------------------------------------------------------------------*/ static void mdbx_winnt_import(void);
/* rthc */
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; (void)reserved;
switch (reason) { switch (reason) {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
mdbx_winnt_import();
mdbx_rthc_global_init(); mdbx_rthc_global_init();
break; break;
case DLL_PROCESS_DETACH: 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* */ /* *INDENT-OFF* */
/* clang-format off */ /* clang-format off */
#if defined(_MSC_VER) #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 */ /* kick a linker to create the TLS directory if not already done */
# pragma comment(linker, "/INCLUDE:_tls_used") # pragma comment(linker, "/INCLUDE:_tls_used")
/* Force some symbol references. */ /* Force some symbol references. */
# pragma comment(linker, "/INCLUDE:mdbx_tls_callback") # pragma comment(linker, "/INCLUDE:mdbx_tls_anchor")
/* specific const-segment for WIN64 */ /* specific const-segment for WIN64 */
# pragma const_seg(".CRT$XLB") # pragma const_seg(".CRT$XLB")
const 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 */ /* kick a linker to create the TLS directory if not already done */
# pragma comment(linker, "/INCLUDE:__tls_used") # pragma comment(linker, "/INCLUDE:__tls_used")
/* Force some symbol references. */ /* Force some symbol references. */
# pragma comment(linker, "/INCLUDE:_mdbx_tls_callback") # pragma comment(linker, "/INCLUDE:_mdbx_tls_anchor")
/* specific data-segment for WIN32 */ /* specific data-segment for WIN32 */
# pragma data_seg(".CRT$XLB") # pragma data_seg(".CRT$XLB")
# endif # 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 data_seg(pop)
# pragma const_seg(pop) # pragma const_seg(pop)
@ -76,13 +81,13 @@ static void NTAPI tls_callback(PVOID module, DWORD reason, PVOID reserved) {
# ifdef _WIN64 # ifdef _WIN64
const const
# endif # endif
PIMAGE_TLS_CALLBACK mdbx_tls_callback __attribute__((section(".CRT$XLB"), used)) PIMAGE_TLS_CALLBACK mdbx_tls_anchor __attribute__((section(".CRT$XLB"), used)) = mdbx_dll_callback;
= tls_callback;
#else #else
# error FIXME # error FIXME
#endif #endif
/* *INDENT-ON* */ /* *INDENT-ON* */
/* clang-format 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; 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"); HINSTANCE hInst = GetModuleHandleA("kernel32.dll");
MDBX_srwlock_function init = MDBX_srwlock_function init =
(MDBX_srwlock_function)GetProcAddress(hInst, "InitializeSRWLock"); (MDBX_srwlock_function)GetProcAddress(hInst, "InitializeSRWLock");
if (init != NULL) { if (init != NULL) {
mdbx_srwlock_Init = init;
mdbx_srwlock_AcquireShared = mdbx_srwlock_AcquireShared =
(MDBX_srwlock_function)GetProcAddress(hInst, "AcquireSRWLockShared"); (MDBX_srwlock_function)GetProcAddress(hInst, "AcquireSRWLockShared");
mdbx_srwlock_ReleaseShared = mdbx_srwlock_ReleaseShared =
@ -657,19 +669,10 @@ static void WINAPI srwlock_thunk_init(MDBX_srwlock *srwl) {
mdbx_srwlock_ReleaseExclusive = mdbx_srwlock_ReleaseExclusive =
(MDBX_srwlock_function)GetProcAddress(hInst, "ReleaseSRWLockExclusive"); (MDBX_srwlock_function)GetProcAddress(hInst, "ReleaseSRWLockExclusive");
} else { } else {
init = stub_srwlock_Init; mdbx_srwlock_Init = stub_srwlock_Init;
mdbx_srwlock_AcquireShared = stub_srwlock_AcquireShared; mdbx_srwlock_AcquireShared = stub_srwlock_AcquireShared;
mdbx_srwlock_ReleaseShared = stub_srwlock_ReleaseShared; mdbx_srwlock_ReleaseShared = stub_srwlock_ReleaseShared;
mdbx_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive; mdbx_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive;
mdbx_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive; 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;