From 60fed8bbca70e89245a0d146ad1ed702249c4427 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Fri, 26 May 2017 20:28:09 +0300 Subject: [PATCH] mdbx: fix first-rdonly-blocker bug. --- src/bits.h | 3 ++- src/mdbx.c | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/bits.h b/src/bits.h index 6479b11d..76a6b9a8 100644 --- a/src/bits.h +++ b/src/bits.h @@ -337,7 +337,8 @@ typedef struct MDBX_lockinfo { /* Format of this lock file. Must be set to MDBX_LOCK_FORMAT. */ uint64_t mti_format; /* Flags which environment was opened. */ - uint64_t mti_envmode; + uint32_t mti_envmode; + uint32_t mti_reserved; #ifdef MDBX_OSAL_LOCK MDBX_OSAL_LOCK mti_wmutex; diff --git a/src/mdbx.c b/src/mdbx.c index d12b3834..c2cf517f 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -4342,7 +4342,7 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, const unsigned mode_flags = MDBX_WRITEMAP | MDBX_NOSYNC | MDBX_NOMETASYNC | MDBX_MAPASYNC; if (lck_rc == MDBX_RESULT_TRUE) { - env->me_lck->mti_envmode = env->me_flags & mode_flags; + env->me_lck->mti_envmode = env->me_flags & (mode_flags | MDBX_RDONLY); if (exclusive == NULL || *exclusive < 2) { /* LY: downgrade lock only if exclusive access not requested. * in case exclusive==1, just leave value as is. */ @@ -4356,11 +4356,19 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, /* LY: just indicate that is not an exclusive access. */ *exclusive = 0; } - if ((env->me_flags & MDBX_RDONLY) == 0 && - ((env->me_lck->mti_envmode ^ env->me_flags) & mode_flags) != 0) { - mdbx_error("current mode/flags incompatible with requested"); - rc = MDBX_INCOMPATIBLE; - goto bailout; + if ((env->me_flags & MDBX_RDONLY) == 0) { + while (env->me_lck->mti_envmode == MDBX_RDONLY) { + if (mdbx_atomic_compare_and_swap32(&env->me_lck->mti_envmode, + MDBX_RDONLY, + env->me_flags & mode_flags)) + break; + /* TODO: yield/relax cpu */ + } + if ((env->me_lck->mti_envmode ^ env->me_flags) & mode_flags) { + mdbx_error("current mode/flags incompatible with requested"); + rc = MDBX_INCOMPATIBLE; + goto bailout; + } } }