mdbx: переделка env_owned_wrtxn() и мест её вызова (backport).

Цель в том чтобы избавить от коллизии блокировки возникающей внутри
dxb_sanitize_tail() при использовании Valgrind/ASAN, а также упросить
код.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2025-03-03 01:48:36 +03:00
parent d313008d82
commit 5e714ed946
6 changed files with 29 additions and 27 deletions

View File

@@ -958,8 +958,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
const bool txn0_owned = env->basal_txn && env_txn0_owned(env);
const bool inside_txn = txn0_owned && env->txn;
MDBX_txn *const txn_owned = env_owned_wrtxn(env);
bool should_unlock = false;
#if MDBX_DEBUG && 0 /* минимальные шаги для проверки/отладки уже не нужны */
@@ -975,7 +974,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
if (unlikely(env->flags & MDBX_RDONLY))
return LOG_IFERR(MDBX_EACCESS);
if (!txn0_owned) {
if (!txn_owned) {
int err = lck_txn_lock(env, false);
if (unlikely(err != MDBX_SUCCESS))
return LOG_IFERR(err);
@@ -989,8 +988,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
/* get untouched params from current TXN or DB */
if (pagesize <= 0 || pagesize >= INT_MAX)
pagesize = env->ps;
const geo_t *const geo =
inside_txn ? &env->txn->geo : &meta_recent(env, &env->basal_txn->tw.troika).ptr_c->geometry;
const geo_t *const geo = env->txn ? &env->txn->geo : &meta_recent(env, &env->basal_txn->tw.troika).ptr_c->geometry;
if (size_lower < 0)
size_lower = pgno2bytes(env, geo->lower);
if (size_now < 0)
@@ -1015,7 +1013,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
size_now = usedbytes;
} else {
/* env NOT yet mapped */
if (unlikely(inside_txn))
if (unlikely(env->txn))
return LOG_IFERR(MDBX_PANIC);
/* is requested some auto-value for pagesize ? */
@@ -1204,8 +1202,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
ENSURE(env, pagesize == (intptr_t)env->ps);
meta_t meta;
memset(&meta, 0, sizeof(meta));
if (!inside_txn) {
eASSERT(env, should_unlock);
if (!env->txn) {
const meta_ptr_t head = meta_recent(env, &env->basal_txn->tw.troika);
uint64_t timestamp = 0;
@@ -1295,7 +1292,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t si
if (unlikely(rc != MDBX_SUCCESS))
goto bailout;
}
if (inside_txn) {
if (env->txn) {
env->txn->geo = new_geo;
env->txn->flags |= MDBX_TXN_DIRTY;
} else {
@@ -1420,17 +1417,17 @@ __cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, MDBX_stat
if (unlikely(err != MDBX_SUCCESS))
return LOG_IFERR(err);
if (env->txn && env_txn0_owned(env))
MDBX_txn *txn_owned = env_owned_wrtxn(env);
if (txn_owned)
/* inside write-txn */
return LOG_IFERR(stat_acc(env->txn, dest, bytes));
return LOG_IFERR(stat_acc(txn_owned, dest, bytes));
MDBX_txn *tmp_txn;
err = mdbx_txn_begin((MDBX_env *)env, nullptr, MDBX_TXN_RDONLY, &tmp_txn);
err = mdbx_txn_begin((MDBX_env *)env, nullptr, MDBX_TXN_RDONLY, &txn_owned);
if (unlikely(err != MDBX_SUCCESS))
return LOG_IFERR(err);
const int rc = stat_acc(tmp_txn, dest, bytes);
err = mdbx_txn_abort(tmp_txn);
const int rc = stat_acc(txn_owned, dest, bytes);
err = mdbx_txn_abort(txn_owned);
if (unlikely(err != MDBX_SUCCESS))
return LOG_IFERR(err);
return LOG_IFERR(rc);