mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:14:12 +08:00
mdbx: refine mdb_meta_head_r().
Change-Id: I038862b3dada408de46f24175513d7522b1f89f5
This commit is contained in:
parent
340da0fd7a
commit
4d9c0657d9
68
mdb.c
68
mdb.c
@ -1883,54 +1883,44 @@ static MDB_meta* mdb_meta_head_w(MDB_env *env) {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static MDB_meta*
|
||||||
MDB_meta* mdb_meta_head_r(MDB_env *env) {
|
mdb_meta_head_r(MDB_env *env) {
|
||||||
MDB_meta* a = METAPAGE_1(env);
|
MDB_meta* a = METAPAGE_1(env);
|
||||||
MDB_meta* b = METAPAGE_2(env), *h;
|
MDB_meta* b = METAPAGE_2(env), *h;
|
||||||
txnid_t head_txnid;
|
|
||||||
int loop = 0, rc;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
#ifdef __SANITIZE_THREAD__
|
|
||||||
pthread_mutex_lock(&tsan_mutex);
|
|
||||||
#endif
|
|
||||||
head_txnid = env->me_txns->mti_txnid;
|
|
||||||
|
|
||||||
mdb_assert(env, a->mm_txnid != b->mm_txnid || head_txnid == 0);
|
|
||||||
if (likely(a->mm_txnid == head_txnid)) {
|
|
||||||
#ifdef __SANITIZE_THREAD__
|
|
||||||
pthread_mutex_unlock(&tsan_mutex);
|
|
||||||
#endif
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
if (likely(b->mm_txnid == head_txnid)) {
|
|
||||||
#ifdef __SANITIZE_THREAD__
|
|
||||||
pthread_mutex_unlock(&tsan_mutex);
|
|
||||||
#endif
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __SANITIZE_THREAD__
|
#ifdef __SANITIZE_THREAD__
|
||||||
pthread_mutex_unlock(&tsan_mutex);
|
pthread_mutex_lock(&tsan_mutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* LY: got a race on env->me_txns->mti_txnid with mdb_env_sync0() */
|
txnid_t head_txnid = env->me_txns->mti_txnid;
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
mdb_assert(env, a->mm_txnid != b->mm_txnid || head_txnid == 0);
|
||||||
__asm__ __volatile__("pause");
|
if (likely(a->mm_txnid == head_txnid)) {
|
||||||
#endif
|
h = a;
|
||||||
|
} else if (likely(b->mm_txnid == head_txnid)) {
|
||||||
|
h = b;
|
||||||
|
} else {
|
||||||
|
/* LY: seems got a race with mdb_env_sync0() */
|
||||||
mdb_coherent_barrier();
|
mdb_coherent_barrier();
|
||||||
loop += 1;
|
head_txnid = env->me_txns->mti_txnid;
|
||||||
if(likely(loop < 3))
|
mdb_assert(env, a->mm_txnid != b->mm_txnid || head_txnid == 0);
|
||||||
continue;
|
|
||||||
if(unlikely(loop > 5))
|
if (likely(a->mm_txnid == head_txnid)) {
|
||||||
break;
|
h = a;
|
||||||
pthread_yield();
|
} else if (likely(b->mm_txnid == head_txnid)) {
|
||||||
|
h = b;
|
||||||
|
} else {
|
||||||
|
/* LY: got a race again, or DB is corrupted */
|
||||||
|
int rc = mdb_mutex_lock(env, MDB_MUTEX(env, w));
|
||||||
|
h = mdb_meta_head_w(env);
|
||||||
|
if (rc == 0)
|
||||||
|
mdb_mutex_unlock(env, MDB_MUTEX(env, w));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mdb_mutex_lock(env, MDB_MUTEX(env, w));
|
#ifdef __SANITIZE_THREAD__
|
||||||
h = mdb_meta_head_w(env);
|
pthread_mutex_unlock(&tsan_mutex);
|
||||||
if (rc == 0)
|
#endif
|
||||||
mdb_mutex_unlock(env, MDB_MUTEX(env, w));
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user