mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:04:13 +08:00
mdbx: workaround for Windows LockFileEx/WriteFile bug.
This resolves https://github.com/leo-yuriev/libmdbx/issues/25
This commit is contained in:
parent
5c9baa06b9
commit
5cfec7a832
@ -743,6 +743,8 @@ struct MDBX_env {
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
SRWLOCK me_remap_guard;
|
SRWLOCK me_remap_guard;
|
||||||
|
/* Workaround for LockFileEx and WriteFile multithread bug */
|
||||||
|
CRITICAL_SECTION me_windowsbug_lock;
|
||||||
#else
|
#else
|
||||||
mdbx_fastmutex_t me_remap_guard;
|
mdbx_fastmutex_t me_remap_guard;
|
||||||
#endif
|
#endif
|
||||||
|
@ -127,16 +127,26 @@ static __inline BOOL funlock(mdbx_filehandle_t fd, uint64_t offset,
|
|||||||
#define LCK_WHOLE 0, LCK_MAXLEN
|
#define LCK_WHOLE 0, LCK_MAXLEN
|
||||||
|
|
||||||
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||||
|
if (dontwait) {
|
||||||
|
if (!TryEnterCriticalSection(&env->me_windowsbug_lock))
|
||||||
|
return MDBX_BUSY;
|
||||||
|
} else {
|
||||||
|
EnterCriticalSection(&env->me_windowsbug_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (flock(env->me_fd, dontwait ? (LCK_EXCLUSIVE | LCK_DONTWAIT)
|
if (flock(env->me_fd, dontwait ? (LCK_EXCLUSIVE | LCK_DONTWAIT)
|
||||||
: (LCK_EXCLUSIVE | LCK_WAITFOR),
|
: (LCK_EXCLUSIVE | LCK_WAITFOR),
|
||||||
LCK_BODY))
|
LCK_BODY))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
int rc = GetLastError();
|
int rc = GetLastError();
|
||||||
|
LeaveCriticalSection(&env->me_windowsbug_lock);
|
||||||
return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY;
|
return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mdbx_txn_unlock(MDBX_env *env) {
|
void mdbx_txn_unlock(MDBX_env *env) {
|
||||||
if (!funlock(env->me_fd, LCK_BODY))
|
int rc = funlock(env->me_fd, LCK_BODY);
|
||||||
|
LeaveCriticalSection(&env->me_windowsbug_lock);
|
||||||
|
if (!rc)
|
||||||
mdbx_panic("%s failed: errcode %u", mdbx_func_, GetLastError());
|
mdbx_panic("%s failed: errcode %u", mdbx_func_, GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4450,6 +4450,7 @@ int __cold mdbx_env_create(MDBX_env **penv) {
|
|||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
InitializeSRWLock(&env->me_remap_guard);
|
InitializeSRWLock(&env->me_remap_guard);
|
||||||
|
InitializeCriticalSection(&env->me_windowsbug_lock);
|
||||||
#else
|
#else
|
||||||
rc = mdbx_fastmutex_init(&env->me_remap_guard);
|
rc = mdbx_fastmutex_init(&env->me_remap_guard);
|
||||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
@ -5487,6 +5488,14 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) {
|
|||||||
|
|
||||||
mdbx_env_close0(env);
|
mdbx_env_close0(env);
|
||||||
mdbx_ensure(env, mdbx_fastmutex_destroy(&env->me_dbi_lock) == MDBX_SUCCESS);
|
mdbx_ensure(env, mdbx_fastmutex_destroy(&env->me_dbi_lock) == MDBX_SUCCESS);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
/* me_remap_guard don't have destructor (Slim Reader/Writer Lock) */
|
||||||
|
DeleteCriticalSection(&env->me_windowsbug_lock);
|
||||||
|
#else
|
||||||
|
mdbx_ensure(env,
|
||||||
|
mdbx_fastmutex_destroy(&env->me_remap_guard) == MDBX_SUCCESS);
|
||||||
|
#endif /* Windows */
|
||||||
|
|
||||||
env->me_signature = 0;
|
env->me_signature = 0;
|
||||||
free(env);
|
free(env);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user