mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-10-31 15:38:57 +08:00 
			
		
		
		
	mdbx: use mdbx_jitter4testing() for race detection.
This commit is contained in:
		| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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_, | ||||
|   | ||||
							
								
								
									
										30
									
								
								src/mdbx.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								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)) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user