diff --git a/src/bits.h b/src/bits.h index 0d7d98d7..7d6fca09 100644 --- a/src/bits.h +++ b/src/bits.h @@ -815,8 +815,11 @@ int mdbx_reader_check0(MDB_env *env, int rlocked, int *dead); (&((MDB_metabuf *)((env)->me_map + env->me_psize))->mb_metabuf.mm_meta) static __inline MDB_meta *mdbx_meta_head(MDB_env *env) { + mdbx_jitter4testing(true); MDB_meta *a = METAPAGE_1(env); + mdbx_jitter4testing(true); MDB_meta *b = METAPAGE_2(env); + mdbx_jitter4testing(true); return (a->mm_txnid > b->mm_txnid) ? a : b; } diff --git a/src/lck-windows.c b/src/lck-windows.c index c9d43151..1de72935 100644 --- a/src/lck-windows.c +++ b/src/lck-windows.c @@ -193,7 +193,7 @@ static int internal_seize_lck(HANDLE lfd) { assert(lfd != INVALID_HANDLE_VALUE); /* 1) now on ?-? (free), get ?-E (middle) */ - jitter4testing(); + mdbx_jitter4testing(false); if (!flock(lfd, LCK_EXCLUSIVE | LCK_WAITFOR, LCK_UPPER)) { rc = GetLastError() /* 2) something went wrong, give up */; mdbx_error("%s(%s) failed: errcode %u", mdbx_func_, @@ -202,13 +202,13 @@ static int internal_seize_lck(HANDLE lfd) { } /* 3) now on ?-E (middle), try E-E (exclusive) */ - jitter4testing(); + mdbx_jitter4testing(false); if (flock(lfd, LCK_EXCLUSIVE | LCK_DONTWAIT, LCK_LOWER)) return MDBX_RESULT_TRUE; /* 4) got E-E (exclusive), done */ /* 5) still on ?-E (middle) */ rc = GetLastError(); - jitter4testing(); + mdbx_jitter4testing(false); if (rc != ERROR_SHARING_VIOLATION && rc != ERROR_LOCK_VIOLATION) { /* 6) something went wrong, give up */ if (!funlock(lfd, LCK_UPPER)) { @@ -220,11 +220,11 @@ static int internal_seize_lck(HANDLE lfd) { } /* 7) still on ?-E (middle), try S-E (locked) */ - jitter4testing(); + mdbx_jitter4testing(false); rc = flock(lfd, LCK_SHARED | LCK_DONTWAIT, LCK_LOWER) ? MDBX_RESULT_FALSE : GetLastError(); - jitter4testing(); + mdbx_jitter4testing(false); if (rc != MDBX_RESULT_FALSE) mdbx_error("%s(%s) failed: errcode %u", mdbx_func_, "?-E(middle) >> S-E(locked)", rc); @@ -247,7 +247,7 @@ int mdbx_lck_seize(MDB_env *env) { assert(env->me_fd != INVALID_HANDLE_VALUE); if (env->me_lfd == INVALID_HANDLE_VALUE) { /* LY: without-lck mode (e.g. on read-only filesystem) */ - jitter4testing(); + mdbx_jitter4testing(false); if (!flock(env->me_fd, LCK_SHARED | LCK_DONTWAIT, LCK_WHOLE)) { rc = GetLastError(); mdbx_error("%s(%s) failed: errcode %u", mdbx_func_, "without-lck", rc); @@ -257,7 +257,7 @@ int mdbx_lck_seize(MDB_env *env) { } rc = internal_seize_lck(env->me_lfd); - jitter4testing(); + mdbx_jitter4testing(false); if (rc == MDBX_RESULT_TRUE && (env->me_flags & MDB_RDONLY) == 0) { /* Check that another process don't operates in without-lck mode. * Doing such check by exclusive locking the body-part of db. Should be @@ -269,10 +269,10 @@ int mdbx_lck_seize(MDB_env *env) { rc = GetLastError(); mdbx_error("%s(%s) failed: errcode %u", mdbx_func_, "lock-against-without-lck", rc); - jitter4testing(); + mdbx_jitter4testing(false); mdbx_lck_destroy(env); } else { - jitter4testing(); + mdbx_jitter4testing(false); if (!funlock(env->me_fd, LCK_BODY)) { rc = GetLastError(); mdbx_panic("%s(%s) failed: errcode %u", mdbx_func_, diff --git a/src/mdbx.c b/src/mdbx.c index d4610ca1..42557d94 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -1412,6 +1412,7 @@ static txnid_t mdbx_find_oldest(MDB_env *env, int *laggard) { const MDB_reader *const r = env->me_lck->mti_readers; for (reader = -1, i = env->me_lck->mti_numreaders; --i >= 0;) { if (r[i].mr_pid) { + mdbx_jitter4testing(true); txnid_t snap = r[i].mr_txnid; if (oldest > snap) { oldest = snap; @@ -2187,9 +2188,13 @@ static int mdbx_txn_renew0(MDB_txn *txn, unsigned flags) { while (1) { MDB_meta *const meta = mdbx_meta_head(txn->mt_env); + mdbx_jitter4testing(false); const txnid_t snap = meta->mm_txnid; + mdbx_jitter4testing(false); r->mr_txnid = snap; + mdbx_jitter4testing(false); mdbx_coherent_barrier(); + mdbx_jitter4testing(true); /* Snap the state from current meta-head */ txn->mt_txnid = snap; @@ -2206,21 +2211,16 @@ static int mdbx_txn_renew0(MDB_txn *txn, unsigned flags) { txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */ } else { /* Not yet touching txn == env->me_txn0, it may be active */ + mdbx_jitter4testing(false); rc = mdbx_txn_lock(env); if (unlikely(rc)) return rc; + mdbx_jitter4testing(false); MDB_meta *meta = mdbx_meta_head(env); + mdbx_jitter4testing(false); txn->mt_canary = meta->mm_canary; txn->mt_txnid = meta->mm_txnid + 1; - if (unlikely(txn->mt_txnid < meta->mm_txnid)) { - mdbx_debug("txnid overflow!"); - rc = MDB_TXN_FULL; - goto bailout; - } - - txn->mt_flags = flags; - #if MDB_DEBUG if (unlikely(txn->mt_txnid == mdbx_debug_edge)) { if (!mdbx_debug_logger) @@ -2230,6 +2230,13 @@ static int mdbx_txn_renew0(MDB_txn *txn, unsigned flags) { "on/off edge (txn %zu)", txn->mt_txnid); } #endif + if (unlikely(txn->mt_txnid < meta->mm_txnid)) { + mdbx_debug("txnid overflow!"); + rc = MDB_TXN_FULL; + goto bailout; + } + + txn->mt_flags = flags; txn->mt_child = NULL; txn->mt_loose_pgs = NULL; txn->mt_loose_count = 0; @@ -3834,6 +3841,13 @@ static int __cold mdbx_setup_lck(MDB_env *env, char *lck_pathname, int mode) { off_t wanna = roundup2((env->me_maxreaders - 1) * sizeof(MDB_reader) + sizeof(MDBX_lockinfo), env->me_os_psize); +#ifndef NDEBUG + err = mdbx_ftruncate(env->me_lfd, size = 0); + if (unlikely(err != MDB_SUCCESS)) + return err; +#endif + mdbx_jitter4testing(false); + if (size != wanna) { err = mdbx_ftruncate(env->me_lfd, wanna); if (unlikely(err != MDB_SUCCESS))