mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 15:44:14 +08:00
mdbx: avoid tran-trap in mdb_txn_renew0() by mt_flags.
Avoid read txn-flags from shared write TXN (e.g. env->me_tnx0->mt_flags) without holding a write-mutex. Change-Id: I3a3a64597f69b7df205043c567a51fe509247826
This commit is contained in:
parent
6069149b05
commit
50c480e2de
21
mdb.c
21
mdb.c
@ -2700,11 +2700,11 @@ mdb_reader_pid(MDB_env *env, int op, pid_t pid)
|
|||||||
* @return 0 on success, non-zero on failure.
|
* @return 0 on success, non-zero on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mdb_txn_renew0(MDB_txn *txn)
|
mdb_txn_renew0(MDB_txn *txn, unsigned flags)
|
||||||
{
|
{
|
||||||
MDB_env *env = txn->mt_env;
|
MDB_env *env = txn->mt_env;
|
||||||
MDB_meta *meta;
|
MDB_meta *meta;
|
||||||
unsigned i, nr, flags = txn->mt_flags;
|
unsigned i, nr;
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
int rc, new_notls = 0;
|
int rc, new_notls = 0;
|
||||||
|
|
||||||
@ -2713,9 +2713,11 @@ mdb_txn_renew0(MDB_txn *txn)
|
|||||||
return MDB_PANIC;
|
return MDB_PANIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags &= MDB_TXN_RDONLY) != 0) {
|
if (flags & MDB_TXN_RDONLY) {
|
||||||
struct MDB_rthc *rthc = NULL;
|
struct MDB_rthc *rthc = NULL;
|
||||||
MDB_reader *r = NULL;
|
MDB_reader *r = NULL;
|
||||||
|
|
||||||
|
txn->mt_flags = MDB_TXN_RDONLY;
|
||||||
if (likely(env->me_flags & MDB_ENV_TXKEY)) {
|
if (likely(env->me_flags & MDB_ENV_TXKEY)) {
|
||||||
mdb_assert(env, !(env->me_flags & MDB_NOTLS));
|
mdb_assert(env, !(env->me_flags & MDB_NOTLS));
|
||||||
rthc = pthread_getspecific(env->me_txkey);
|
rthc = pthread_getspecific(env->me_txkey);
|
||||||
@ -2811,9 +2813,9 @@ mdb_txn_renew0(MDB_txn *txn)
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
meta = mdb_meta_head_w(env);
|
meta = mdb_meta_head_w(env);
|
||||||
txn->mt_txnid = meta->mm_txnid;
|
txn->mt_txnid = meta->mm_txnid + 1;
|
||||||
|
txn->mt_flags = flags;
|
||||||
|
|
||||||
txn->mt_txnid++;
|
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
if (unlikely(txn->mt_txnid == mdb_debug_edge)) {
|
if (unlikely(txn->mt_txnid == mdb_debug_edge)) {
|
||||||
if (! mdb_debug_logger)
|
if (! mdb_debug_logger)
|
||||||
@ -2842,8 +2844,6 @@ mdb_txn_renew0(MDB_txn *txn)
|
|||||||
txn->mt_next_pgno = meta->mm_last_pg+1;
|
txn->mt_next_pgno = meta->mm_last_pg+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
txn->mt_flags = flags;
|
|
||||||
|
|
||||||
/* Setup db info */
|
/* Setup db info */
|
||||||
txn->mt_numdbs = env->me_numdbs;
|
txn->mt_numdbs = env->me_numdbs;
|
||||||
for (i=CORE_DBS; i<txn->mt_numdbs; i++) {
|
for (i=CORE_DBS; i<txn->mt_numdbs; i++) {
|
||||||
@ -2880,7 +2880,7 @@ mdb_txn_renew(MDB_txn *txn)
|
|||||||
if (unlikely(!F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED)))
|
if (unlikely(!F_ISSET(txn->mt_flags, MDB_TXN_RDONLY|MDB_TXN_FINISHED)))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
rc = mdb_txn_renew0(txn);
|
rc = mdb_txn_renew0(txn, MDB_TXN_RDONLY);
|
||||||
if (rc == MDB_SUCCESS) {
|
if (rc == MDB_SUCCESS) {
|
||||||
mdb_debug("renew txn %zu%c %p on mdbenv %p, root page %zu",
|
mdb_debug("renew txn %zu%c %p on mdbenv %p, root page %zu",
|
||||||
txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
|
txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
|
||||||
@ -2988,13 +2988,12 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned flags, MDB_txn **ret)
|
|||||||
} else { /* MDB_RDONLY */
|
} else { /* MDB_RDONLY */
|
||||||
txn->mt_dbiseqs = env->me_dbiseqs;
|
txn->mt_dbiseqs = env->me_dbiseqs;
|
||||||
renew:
|
renew:
|
||||||
rc = mdb_txn_renew0(txn);
|
rc = mdb_txn_renew0(txn, flags);
|
||||||
}
|
}
|
||||||
if (unlikely(rc)) {
|
if (unlikely(rc)) {
|
||||||
if (txn != env->me_txn0)
|
if (txn != env->me_txn0)
|
||||||
free(txn);
|
free(txn);
|
||||||
} else {
|
} else {
|
||||||
txn->mt_flags |= flags; /* could not change txn=me_txn0 earlier */
|
|
||||||
txn->mt_signature = MDBX_MT_SIGNATURE;
|
txn->mt_signature = MDBX_MT_SIGNATURE;
|
||||||
*ret = txn;
|
*ret = txn;
|
||||||
mdb_debug("begin txn %zu%c %p on mdbenv %p, root page %zu",
|
mdb_debug("begin txn %zu%c %p on mdbenv %p, root page %zu",
|
||||||
@ -9306,7 +9305,7 @@ mdb_env_copyfd0(MDB_env *env, HANDLE fd)
|
|||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
rc = mdb_txn_renew0(txn);
|
rc = mdb_txn_renew0(txn, MDB_RDONLY);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
mdb_mutex_unlock(env, wmutex);
|
mdb_mutex_unlock(env, wmutex);
|
||||||
goto leave;
|
goto leave;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user