diff options
author | George Hazan <ghazan@miranda.im> | 2018-02-05 12:52:46 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2018-02-05 12:52:46 +0300 |
commit | 7aa0aa3230ef5a94e75093fcd549cd4bff0ff7d0 (patch) | |
tree | 0afc8cd4e7f28e0474ae707454e87d811ab96421 /plugins/Dbx_mdbx/src | |
parent | 2edf9516a5442149fcadd241f8cb875c79de6841 (diff) |
merge of libmdbx
Diffstat (limited to 'plugins/Dbx_mdbx/src')
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/mdbx.h | 18 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/bits.h | 21 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/defs.h | 6 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/lck-posix.c | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c | 14 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c | 192 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/osal.c | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/osal.h | 2 | ||||
-rw-r--r-- | plugins/Dbx_mdbx/src/libmdbx/src/version.c | 2 |
9 files changed, 183 insertions, 76 deletions
diff --git a/plugins/Dbx_mdbx/src/libmdbx/mdbx.h b/plugins/Dbx_mdbx/src/libmdbx/mdbx.h index 8df5f4a350..4daf525f6a 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/mdbx.h +++ b/plugins/Dbx_mdbx/src/libmdbx/mdbx.h @@ -1,6 +1,6 @@ /* LICENSE AND COPYRUSTING ***************************************************** * - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -60,14 +60,11 @@ /* IMPENDING CHANGES WARNING *************************************************** * - * Now MDBX is under active development and until November 2017 is expected a - * big change both of API and database format. Unfortunately those update will - * lead to loss of compatibility with previous versions. + * MDBX is under active development, database format and API aren't stable + * at least until 2018Q2. New version won't be backwards compatible. Main focus + * of the rework is to provide clear and robust API and new features. * - * The aim of this revolution in providing a clearer robust API and adding new - * features, including the database properties. */ - -/*--------------------------------------------------------------------------*/ + ******************************************************************************/ #ifdef _MSC_VER #pragma warning(push, 1) @@ -478,6 +475,8 @@ typedef struct MDBX_envinfo { uint64_t mi_last_pgno; /* ID of the last used page */ uint64_t mi_recent_txnid; /* ID of the last committed transaction */ uint64_t mi_latter_reader_txnid; /* ID of the last reader transaction */ + uint64_t mi_self_latter_reader_txnid; /* ID of the last reader transaction of + caller process */ uint64_t mi_meta0_txnid, mi_meta0_sign; uint64_t mi_meta1_txnid, mi_meta1_sign; uint64_t mi_meta2_txnid, mi_meta2_sign; @@ -1155,7 +1154,8 @@ LIBMDBX_API int mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat, * Returns A non-zero error value on failure and 0 on success. */ #define MDBX_TBL_DIRTY 0x01 /* DB was written in this txn */ #define MDBX_TBL_STALE 0x02 /* Named-DB record is older than txnID */ -#define MDBX_TBL_NEW 0x04 /* Named-DB handle opened in this txn */ +#define MDBX_TBL_FRESH 0x04 /* Named-DB handle opened in this txn */ +#define MDBX_TBL_CREAT 0x08 /* Named-DB handle created in this txn */ LIBMDBX_API int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags, unsigned *state); LIBMDBX_API int mdbx_dbi_flags(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags); diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h index 6915202ae6..a714ae733c 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/bits.h +++ b/plugins/Dbx_mdbx/src/libmdbx/src/bits.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -539,10 +539,11 @@ struct MDBX_txn { /* Transaction DB Flags */ #define DB_DIRTY MDBX_TBL_DIRTY /* DB was written in this txn */ #define DB_STALE MDBX_TBL_STALE /* Named-DB record is older than txnID */ -#define DB_NEW MDBX_TBL_NEW /* Named-DB handle opened in this txn */ -#define DB_VALID 0x08 /* DB handle is valid, see also MDBX_VALID */ -#define DB_USRVALID 0x10 /* As DB_VALID, but not set for FREE_DBI */ -#define DB_DUPDATA 0x20 /* DB is MDBX_DUPSORT data */ +#define DB_FRESH MDBX_TBL_FRESH /* Named-DB handle opened in this txn */ +#define DB_CREAT MDBX_TBL_CREAT /* Named-DB handle created in this txn */ +#define DB_VALID 0x10 /* DB handle is valid, see also MDBX_VALID */ +#define DB_USRVALID 0x20 /* As DB_VALID, but not set for FREE_DBI */ +#define DB_DUPDATA 0x40 /* DB is MDBX_DUPSORT data */ /* In write txns, array of cursors for each DB */ MDBX_cursor **mt_cursors; /* Array of flags for each DB */ @@ -743,6 +744,8 @@ struct MDBX_env { #if defined(_WIN32) || defined(_WIN64) MDBX_shlock me_remap_guard; + /* Workaround for LockFileEx and WriteFile multithread bug */ + CRITICAL_SECTION me_windowsbug_lock; #else mdbx_fastmutex_t me_remap_guard; #endif @@ -1177,14 +1180,6 @@ static __inline void SETDSZ(MDBX_node *node, size_t size) { #define MDBX_COMMIT_PAGES IOV_MAX #endif -/* Check txn and dbi arguments to a function */ -#define TXN_DBI_EXIST(txn, dbi, validity) \ - ((dbi) < (txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & (validity))) - -/* Check for misused dbi handles */ -#define TXN_DBI_CHANGED(txn, dbi) \ - ((txn)->mt_dbiseqs[dbi] != (txn)->mt_env->me_dbiseqs[dbi]) - /* LY: fast enough on most systems * * / diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/defs.h b/plugins/Dbx_mdbx/src/libmdbx/src/defs.h index 5190fa3a35..5e6110f8c5 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/defs.h +++ b/plugins/Dbx_mdbx/src/libmdbx/src/defs.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -338,7 +338,7 @@ # define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,s) # define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,s) # endif -#else +#elif !defined(RUNNING_ON_VALGRIND) # define VALGRIND_CREATE_MEMPOOL(h,r,z) # define VALGRIND_DESTROY_MEMPOOL(h) # define VALGRIND_MEMPOOL_TRIM(h,a,s) @@ -357,7 +357,7 @@ #ifdef __SANITIZE_ADDRESS__ # include <sanitizer/asan_interface.h> -#else +#elif !defined(ASAN_POISON_MEMORY_REGION) # define ASAN_POISON_MEMORY_REGION(addr, size) \ ((void)(addr), (void)(size)) # define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/lck-posix.c b/plugins/Dbx_mdbx/src/libmdbx/src/lck-posix.c index 14ce3d504d..5916c40e80 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/lck-posix.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/lck-posix.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c index 0cf908aae0..c29164071d 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/lck-windows.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -88,16 +88,26 @@ static __inline BOOL funlock(mdbx_filehandle_t fd, uint64_t offset, #define LCK_WHOLE 0, LCK_MAXLEN 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) : (LCK_EXCLUSIVE | LCK_WAITFOR), LCK_BODY)) return MDBX_SUCCESS; int rc = GetLastError(); + LeaveCriticalSection(&env->me_windowsbug_lock); return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY; } 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()); } diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c index b3ce3388d5..aac32704a9 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/mdbx.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -2671,6 +2671,7 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) { /* Setup db info */ txn->mt_numdbs = env->me_numdbs; + mdbx_compiler_barrier(); for (unsigned i = CORE_DBS; i < txn->mt_numdbs; i++) { unsigned x = env->me_dbflags[i]; txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS; @@ -2735,7 +2736,8 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags, MDBX_txn **ret) { MDBX_txn *txn; MDBX_ntxn *ntxn; - int rc, size, tsize; + int rc; + unsigned size, tsize; if (unlikely(!env || !ret)) return MDBX_EINVAL; @@ -2787,10 +2789,11 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags, return MDBX_BUSY; goto renew; } - if (unlikely((txn = calloc(1, size)) == NULL)) { + if (unlikely((txn = malloc(size)) == NULL)) { mdbx_debug("calloc: %s", "failed"); return MDBX_ENOMEM; } + memset(txn, 0, tsize); txn->mt_dbxs = env->me_dbxs; /* static */ txn->mt_dbs = (MDBX_db *)((char *)txn + tsize); txn->mt_dbflags = (uint8_t *)txn + size - env->me_maxdbs; @@ -2821,7 +2824,7 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags, memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDBX_db)); /* Copy parent's mt_dbflags, but clear DB_NEW */ for (i = 0; i < txn->mt_numdbs; i++) - txn->mt_dbflags[i] = parent->mt_dbflags[i] & ~DB_NEW; + txn->mt_dbflags[i] = parent->mt_dbflags[i] & ~(DB_FRESH | DB_CREAT); rc = 0; ntxn = (MDBX_ntxn *)txn; ntxn->mnt_pgstate = @@ -2877,27 +2880,39 @@ uint64_t mdbx_txn_id(MDBX_txn *txn) { static void mdbx_dbis_update(MDBX_txn *txn, int keep) { MDBX_dbi n = txn->mt_numdbs; if (n) { + bool locked = false; MDBX_env *env = txn->mt_env; uint8_t *tdbflags = txn->mt_dbflags; for (unsigned i = n; --i >= CORE_DBS;) { - if (tdbflags[i] & DB_NEW) { - if (keep) { - env->me_dbflags[i] = txn->mt_dbs[i].md_flags | MDBX_VALID; - } else { - char *ptr = env->me_dbxs[i].md_name.iov_base; - if (ptr) { - env->me_dbxs[i].md_name.iov_base = NULL; - env->me_dbxs[i].md_name.iov_len = 0; - env->me_dbflags[i] = 0; - env->me_dbiseqs[i]++; - free(ptr); - } + if (likely((tdbflags[i] & DB_CREAT) == 0)) + continue; + if (!locked) { + mdbx_ensure(env, + mdbx_fastmutex_acquire(&env->me_dbi_lock) == MDBX_SUCCESS); + locked = true; + } + if (keep) { + env->me_dbflags[i] = txn->mt_dbs[i].md_flags | MDBX_VALID; + mdbx_compiler_barrier(); + if (env->me_numdbs <= i) + env->me_numdbs = i + 1; + } else { + char *ptr = env->me_dbxs[i].md_name.iov_base; + if (ptr) { + env->me_dbxs[i].md_name.iov_len = 0; + mdbx_compiler_barrier(); + assert(env->me_dbflags[i] == 0); + env->me_dbiseqs[i]++; + env->me_dbxs[i].md_name.iov_base = NULL; + free(ptr); } } } - if (keep && env->me_numdbs < n) - env->me_numdbs = n; + + if (unlikely(locked)) + mdbx_ensure(env, + mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); } } @@ -2914,9 +2929,6 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) { return MDBX_PANIC; } - /* Export or close DBI handles opened in this txn */ - mdbx_dbis_update(txn, mode & MDBX_END_UPDATE); - mdbx_debug("%s txn %" PRIaTXN "%c %p on mdbenv %p, root page %" PRIaPGNO "/%" PRIaPGNO, names[mode & MDBX_END_OPMASK], txn->mt_txnid, @@ -2939,6 +2951,9 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) { txn->mt_flags = MDBX_TXN_RDONLY | MDBX_TXN_FINISHED; txn->mt_owner = 0; } else if (!F_ISSET(txn->mt_flags, MDBX_TXN_FINISHED)) { + /* Export or close DBI handles created in this txn */ + mdbx_dbis_update(txn, mode & MDBX_END_UPDATE); + pgno_t *pghead = env->me_reclaimed_pglist; if (!(mode & MDBX_END_EOTDONE)) /* !(already closed cursors) */ @@ -3562,6 +3577,44 @@ done: return MDBX_SUCCESS; } +/* Check for misused dbi handles */ +#define TXN_DBI_CHANGED(txn, dbi) \ + ((txn)->mt_dbiseqs[dbi] != (txn)->mt_env->me_dbiseqs[dbi]) + +/* Import DBI which opened after txn started into context */ +static __cold bool mdbx_txn_import_dbi(MDBX_txn *txn, MDBX_dbi dbi) { + MDBX_env *env = txn->mt_env; + if (dbi < CORE_DBS || dbi >= env->me_numdbs) + return false; + + mdbx_ensure(env, mdbx_fastmutex_acquire(&env->me_dbi_lock) == MDBX_SUCCESS); + const unsigned snap_numdbs = env->me_numdbs; + mdbx_compiler_barrier(); + for (unsigned i = CORE_DBS; i < snap_numdbs; ++i) { + if (i >= txn->mt_numdbs) + txn->mt_dbflags[i] = 0; + if (!(txn->mt_dbflags[i] & DB_USRVALID) && + (env->me_dbflags[i] & MDBX_VALID)) { + txn->mt_dbs[i].md_flags = env->me_dbflags[i] & PERSISTENT_FLAGS; + txn->mt_dbflags[i] = DB_VALID | DB_USRVALID | DB_STALE; + assert(txn->mt_dbxs[i].md_cmp != NULL); + } + } + txn->mt_numdbs = snap_numdbs; + + mdbx_ensure(env, mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); + return txn->mt_dbflags[dbi] & DB_USRVALID; +} + +/* Check txn and dbi arguments to a function */ +static __inline bool TXN_DBI_EXIST(MDBX_txn *txn, MDBX_dbi dbi, + unsigned validity) { + if (likely(dbi < txn->mt_numdbs && (txn->mt_dbflags[dbi] & validity))) + return true; + + return mdbx_txn_import_dbi(txn, dbi); +} + int mdbx_txn_commit(MDBX_txn *txn) { int rc; @@ -3644,7 +3697,7 @@ int mdbx_txn_commit(MDBX_txn *txn) { for (i = CORE_DBS; i < txn->mt_numdbs; i++) { /* preserve parent's DB_NEW status */ parent->mt_dbflags[i] = - txn->mt_dbflags[i] | (parent->mt_dbflags[i] & DB_NEW); + txn->mt_dbflags[i] | (parent->mt_dbflags[i] & (DB_CREAT | DB_FRESH)); } dst = parent->mt_rw_dirtylist; @@ -4450,6 +4503,7 @@ int __cold mdbx_env_create(MDBX_env **penv) { #if defined(_WIN32) || defined(_WIN64) mdbx_shlock_init(&env->me_remap_guard); + InitializeCriticalSection(&env->me_windowsbug_lock); #else rc = mdbx_fastmutex_init(&env->me_remap_guard); if (unlikely(rc != MDBX_SUCCESS)) { @@ -5281,8 +5335,8 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, env->me_path = mdbx_strdup(path); env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDBX_dbx)); - env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t)); - env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(unsigned)); + env->me_dbflags = calloc(env->me_maxdbs, sizeof(env->me_dbflags[0])); + env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(env->me_dbiseqs[0])); if (!(env->me_dbxs && env->me_path && env->me_dbflags && env->me_dbiseqs)) { rc = MDBX_ENOMEM; goto bailout; @@ -5487,6 +5541,14 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) { mdbx_env_close0(env); 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; free(env); @@ -10099,15 +10161,19 @@ int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) { arg->mi_dxb_pagesize = env->me_psize; arg->mi_sys_pagesize = env->me_os_psize; - arg->mi_latter_reader_txnid = 0; + arg->mi_self_latter_reader_txnid = arg->mi_latter_reader_txnid = 0; if (env->me_lck) { MDBX_reader *r = env->me_lck->mti_readers; - arg->mi_latter_reader_txnid = arg->mi_recent_txnid; + arg->mi_self_latter_reader_txnid = arg->mi_latter_reader_txnid = + arg->mi_recent_txnid; for (unsigned i = 0; i < arg->mi_numreaders; ++i) { - if (r[i].mr_pid) { + const mdbx_pid_t pid = r[i].mr_pid; + if (pid) { const txnid_t txnid = r[i].mr_txnid; if (arg->mi_latter_reader_txnid > txnid) arg->mi_latter_reader_txnid = txnid; + if (pid == env->me_pid && arg->mi_self_latter_reader_txnid > txnid) + arg->mi_self_latter_reader_txnid = txnid; } } } @@ -10205,8 +10271,8 @@ int mdbx_dbi_open_ex(MDBX_txn *txn, const char *table_name, unsigned user_flags, /* Is the DB already open? */ size_t len = strlen(table_name); - MDBX_dbi scan, slot = txn->mt_numdbs; - for (scan = txn->mt_numdbs; --scan >= CORE_DBS;) { + MDBX_dbi scan, slot; + for (slot = scan = txn->mt_numdbs; --scan >= CORE_DBS;) { if (!txn->mt_dbxs[scan].md_name.iov_len) { /* Remember this free slot */ slot = scan; @@ -10261,7 +10327,38 @@ int mdbx_dbi_open_ex(MDBX_txn *txn, const char *table_name, unsigned user_flags, return err; } - unsigned dbflag = DB_NEW | DB_VALID | DB_USRVALID; + if (txn->mt_numdbs < env->me_numdbs) { + for (unsigned i = txn->mt_numdbs; i < env->me_numdbs; ++i) { + txn->mt_dbflags[i] = 0; + if (env->me_dbflags[i] & MDBX_VALID) { + txn->mt_dbs[i].md_flags = env->me_dbflags[i] & PERSISTENT_FLAGS; + txn->mt_dbflags[i] = DB_VALID | DB_USRVALID | DB_STALE; + assert(txn->mt_dbxs[i].md_cmp != NULL); + } + } + txn->mt_numdbs = env->me_numdbs; + } + + for (slot = scan = txn->mt_numdbs; --scan >= CORE_DBS;) { + if (!txn->mt_dbxs[scan].md_name.iov_len) { + /* Remember this free slot */ + slot = scan; + continue; + } + if (len == txn->mt_dbxs[scan].md_name.iov_len && + !strncmp(table_name, txn->mt_dbxs[scan].md_name.iov_base, len)) { + *dbi = scan; + rc = mdbx_dbi_bind(txn, scan, user_flags, keycmp, datacmp); + goto unlock_return_rc; + } + } + + if (unlikely(slot >= env->me_maxdbs)) { + rc = MDBX_DBS_FULL; + goto unlock_return_rc; + } + + unsigned dbflag = DB_FRESH | DB_VALID | DB_USRVALID; if (unlikely(rc)) { /* MDBX_NOTFOUND and MDBX_CREATE: Create new DB */ assert(rc == MDBX_NOTFOUND); @@ -10278,33 +10375,37 @@ int mdbx_dbi_open_ex(MDBX_txn *txn, const char *table_name, unsigned user_flags, if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - dbflag |= DB_DIRTY; + dbflag |= DB_DIRTY | DB_CREAT; } /* Got info, register DBI in this txn */ - txn->mt_dbxs[slot].md_name.iov_base = namedup; - txn->mt_dbxs[slot].md_name.iov_len = len; txn->mt_dbxs[slot].md_cmp = nullptr; txn->mt_dbxs[slot].md_dcmp = nullptr; - txn->mt_dbflags[slot] = (uint8_t)dbflag; - txn->mt_dbiseqs[slot] = (env->me_dbiseqs[slot] += 1); - txn->mt_dbs[slot] = *(MDBX_db *)data.iov_base; + env->me_dbflags[slot] = 0; rc = mdbx_dbi_bind(txn, slot, user_flags, keycmp, datacmp); if (unlikely(rc != MDBX_SUCCESS)) { - assert((dbflag & DB_DIRTY) == 0); - /* cleanup slot */ - txn->mt_dbxs[slot].md_name.iov_base = NULL; - txn->mt_dbxs[slot].md_name.iov_len = 0; - txn->mt_dbflags[slot] = 0; + assert((dbflag & DB_CREAT) == 0); bailout: free(namedup); } else { - *dbi = slot; + txn->mt_dbiseqs[slot] = (env->me_dbiseqs[slot] += 1); + txn->mt_dbflags[slot] = (uint8_t)dbflag; + txn->mt_dbxs[slot].md_name.iov_base = namedup; + mdbx_compiler_barrier(); + txn->mt_dbxs[slot].md_name.iov_len = len; if (slot == txn->mt_numdbs) txn->mt_numdbs++; + if ((dbflag & DB_CREAT) == 0) { + env->me_dbflags[slot] = txn->mt_dbs[slot].md_flags | MDBX_VALID; + mdbx_compiler_barrier(); + if (env->me_numdbs <= slot) + env->me_numdbs = slot + 1; + } + *dbi = slot; } +unlock_return_rc: mdbx_ensure(env, mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); return rc; } @@ -10352,10 +10453,11 @@ static int mdbx_dbi_close_locked(MDBX_env *env, MDBX_dbi dbi) { if (unlikely(!ptr)) return MDBX_BAD_DBI; - env->me_dbxs[dbi].md_name.iov_base = NULL; - env->me_dbxs[dbi].md_name.iov_len = 0; env->me_dbflags[dbi] = 0; + env->me_dbxs[dbi].md_name.iov_len = 0; + mdbx_compiler_barrier(); env->me_dbiseqs[dbi]++; + env->me_dbxs[dbi].md_name.iov_base = NULL; free(ptr); return MDBX_SUCCESS; } @@ -10387,7 +10489,7 @@ int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags, return MDBX_EINVAL; *flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS; - *state = txn->mt_dbflags[dbi] & (DB_NEW | DB_DIRTY | DB_STALE); + *state = txn->mt_dbflags[dbi] & (DB_FRESH | DB_CREAT | DB_DIRTY | DB_STALE); return MDBX_SUCCESS; } diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/osal.c b/plugins/Dbx_mdbx/src/libmdbx/src/osal.c index af0b88ce88..f95ac57a12 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/osal.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/osal.c @@ -1,7 +1,7 @@ /* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h index eb6cd5ee10..54559388c9 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/osal.h +++ b/plugins/Dbx_mdbx/src/libmdbx/src/osal.h @@ -1,7 +1,7 @@ /* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * diff --git a/plugins/Dbx_mdbx/src/libmdbx/src/version.c b/plugins/Dbx_mdbx/src/libmdbx/src/version.c index ef4f99088d..aed4fab508 100644 --- a/plugins/Dbx_mdbx/src/libmdbx/src/version.c +++ b/plugins/Dbx_mdbx/src/libmdbx/src/version.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2017 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2015-2018 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * |