mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-30 22:47:16 +08:00
mdbx: separate transaction flags.
Change-Id: Ib9a0f6946e1ecf35059e2dccc91319ae130c9f9b
This commit is contained in:
parent
5e43ee61a2
commit
1e7a1da14e
40
mdbx.h
40
mdbx.h
@ -986,9 +986,6 @@ enum MDBX_env_flags_t {
|
||||
MDBX_UTTERLY_NOSYNC = MDBX_SAFE_NOSYNC | UINT32_C(0x100000),
|
||||
|
||||
/** @} end of SYNC MODES */
|
||||
|
||||
/** Do not block when starting a write transaction */
|
||||
MDBX_TRYTXN = UINT32_C(0x10000000),
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
/** \ingroup c_opening */
|
||||
@ -997,6 +994,39 @@ typedef enum MDBX_env_flags_t MDBX_env_flags_t;
|
||||
DEFINE_ENUM_FLAG_OPERATORS(MDBX_env_flags_t)
|
||||
#endif
|
||||
|
||||
/** Transaction flags
|
||||
* \ingroup c_transactions
|
||||
* \anchor txn_flags */
|
||||
enum MDBX_txn_flags_t {
|
||||
/** Start read-write transaction.
|
||||
*
|
||||
* Only one write transaction may be active at a time. Writes are fully
|
||||
* serialized, which guarantees that writers can never deadlock. */
|
||||
MDBX_TXN_READWRITE = 0,
|
||||
|
||||
/** Start read-only transaction.
|
||||
*
|
||||
* There can be multiple read-only transactions simultaneously that do not
|
||||
* block each other and a write transactions. */
|
||||
MDBX_TXN_RDONLY = MDBX_RDONLY,
|
||||
|
||||
/** Do not block when starting a write transaction. */
|
||||
MDBX_TXN_TRY = UINT32_C(0x10000000),
|
||||
|
||||
/** Exactly the same as \ref MDBX_NOMETASYNC,
|
||||
* but for this transaction only */
|
||||
MDBX_TXN_NOMETASYNC = MDBX_NOMETASYNC,
|
||||
|
||||
/** Exactly the same as \ref MDBX_SAFE_NOSYNC,
|
||||
* but for this transaction only */
|
||||
MDBX_TXN_NOSYNC = MDBX_SAFE_NOSYNC
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
typedef enum MDBX_txn_flags_t MDBX_txn_flags_t;
|
||||
#else
|
||||
DEFINE_ENUM_FLAG_OPERATORS(MDBX_txn_flags_t)
|
||||
#endif
|
||||
|
||||
/** DATABASE FLAGS
|
||||
* \ingroup c_dbi
|
||||
* \anchor db_flags */
|
||||
@ -2261,8 +2291,8 @@ LIBMDBX_API void *mdbx_env_get_userctx(const MDBX_env *env);
|
||||
* - \ref MDBX_RDONLY This transaction will not perform
|
||||
* any write operations.
|
||||
*
|
||||
* - \ref MDBX_TRYTXN Do not block when starting
|
||||
* a write transaction.
|
||||
* - \ref MDBX_TXN_TRY Do not block when starting
|
||||
* a write transaction.
|
||||
*
|
||||
* - \ref MDBX_SAFE_NOSYNC, \ref MDBX_NOMETASYNC.
|
||||
* Do not sync data to disk corresponding
|
||||
|
98
src/core.c
98
src/core.c
@ -3143,7 +3143,7 @@ static int __must_check_result mdbx_audit_ex(MDBX_txn *txn,
|
||||
bool dont_filter_gc);
|
||||
static __maybe_unused __always_inline int __must_check_result
|
||||
mdbx_audit(MDBX_txn *txn) {
|
||||
return mdbx_audit_ex(txn, 0, (txn->mt_flags & MDBX_RDONLY) != 0);
|
||||
return mdbx_audit_ex(txn, 0, (txn->mt_flags & MDBX_TXN_RDONLY) != 0);
|
||||
}
|
||||
|
||||
static int __must_check_result mdbx_page_check(MDBX_cursor *const mc,
|
||||
@ -4477,7 +4477,7 @@ static const char *mdbx_durable_str(const MDBX_meta *const meta) {
|
||||
|
||||
/* Find oldest txnid still referenced. */
|
||||
static txnid_t mdbx_find_oldest(const MDBX_txn *txn) {
|
||||
mdbx_tassert(txn, (txn->mt_flags & MDBX_RDONLY) == 0);
|
||||
mdbx_tassert(txn, (txn->mt_flags & MDBX_TXN_RDONLY) == 0);
|
||||
MDBX_env *env = txn->mt_env;
|
||||
const txnid_t edge = mdbx_recent_steady_txnid(env);
|
||||
mdbx_tassert(txn, edge <= txn->mt_txnid);
|
||||
@ -6070,9 +6070,9 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
||||
mdbx_assert(env, (flags & ~(MDBX_TXN_BEGIN_FLAGS | MDBX_TXN_SPILLS |
|
||||
MDBX_WRITEMAP)) == 0);
|
||||
const uintptr_t tid = mdbx_thread_self();
|
||||
if (flags & MDBX_RDONLY) {
|
||||
if (flags & MDBX_TXN_RDONLY) {
|
||||
txn->mt_flags =
|
||||
MDBX_RDONLY | (env->me_flags & (MDBX_NOTLS | MDBX_WRITEMAP));
|
||||
MDBX_TXN_RDONLY | (env->me_flags & (MDBX_NOTLS | MDBX_WRITEMAP));
|
||||
MDBX_reader *r = txn->to.reader;
|
||||
STATIC_ASSERT(sizeof(uintptr_t) == sizeof(r->mr_tid));
|
||||
if (likely(env->me_flags & MDBX_ENV_TXKEY)) {
|
||||
@ -6166,7 +6166,7 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
||||
|
||||
/* Not yet touching txn == env->me_txn0, it may be active */
|
||||
mdbx_jitter4testing(false);
|
||||
rc = mdbx_txn_lock(env, F_ISSET(flags, MDBX_TRYTXN));
|
||||
rc = mdbx_txn_lock(env, F_ISSET(flags, MDBX_TXN_TRY));
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
if (unlikely(env->me_flags & MDBX_FATAL_ERROR)) {
|
||||
@ -6239,11 +6239,11 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
||||
}
|
||||
rc = mdbx_mapresize(env, txn->mt_next_pgno, txn->mt_end_pgno,
|
||||
txn->mt_geo.upper,
|
||||
(txn->mt_flags & MDBX_RDONLY) ? true : false);
|
||||
(txn->mt_flags & MDBX_TXN_RDONLY) ? true : false);
|
||||
if (rc != MDBX_SUCCESS)
|
||||
goto bailout;
|
||||
}
|
||||
if (txn->mt_flags & MDBX_RDONLY) {
|
||||
if (txn->mt_flags & MDBX_TXN_RDONLY) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if ((size > env->me_dbgeo.lower && env->me_dbgeo.shrink) ||
|
||||
(mdbx_RunningUnderWine() &&
|
||||
@ -6303,7 +6303,7 @@ static __always_inline int check_txn_rw(const MDBX_txn *txn, int bad_bits) {
|
||||
if (unlikely(txn->mt_flags & bad_bits))
|
||||
return MDBX_BAD_TXN;
|
||||
|
||||
if (unlikely(F_ISSET(txn->mt_flags, MDBX_RDONLY)))
|
||||
if (unlikely(F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)))
|
||||
return MDBX_EACCESS;
|
||||
|
||||
#if MDBX_TXN_CHECKOWNER
|
||||
@ -6321,7 +6321,7 @@ int mdbx_txn_renew(MDBX_txn *txn) {
|
||||
if (unlikely(txn->mt_signature != MDBX_MT_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
|
||||
if (unlikely((txn->mt_flags & MDBX_RDONLY) == 0))
|
||||
if (unlikely((txn->mt_flags & MDBX_TXN_RDONLY) == 0))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
int rc;
|
||||
@ -6331,12 +6331,12 @@ int mdbx_txn_renew(MDBX_txn *txn) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mdbx_txn_renew0(txn, MDBX_RDONLY);
|
||||
rc = mdbx_txn_renew0(txn, MDBX_TXN_RDONLY);
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
txn->mt_owner = mdbx_thread_self();
|
||||
mdbx_debug("renew txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO
|
||||
"/%" PRIaPGNO,
|
||||
txn->mt_txnid, (txn->mt_flags & MDBX_RDONLY) ? 'r' : 'w',
|
||||
txn->mt_txnid, (txn->mt_flags & MDBX_TXN_RDONLY) ? 'r' : 'w',
|
||||
(void *)txn, (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root,
|
||||
txn->mt_dbs[FREE_DBI].md_root);
|
||||
}
|
||||
@ -6374,7 +6374,8 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags,
|
||||
|
||||
if (parent) {
|
||||
/* Nested transactions: Max 1 child, write txns only, no writemap */
|
||||
rc = check_txn_rw(parent, MDBX_RDONLY | MDBX_WRITEMAP | MDBX_TXN_BLOCKED);
|
||||
rc = check_txn_rw(parent,
|
||||
MDBX_TXN_RDONLY | MDBX_WRITEMAP | MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
|
||||
@ -6387,7 +6388,7 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags,
|
||||
/* Child txns save MDBX_pgstate and use own copy of cursors */
|
||||
size = env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1);
|
||||
size += tsize = sizeof(MDBX_txn);
|
||||
} else if (flags & MDBX_RDONLY) {
|
||||
} else if (flags & MDBX_TXN_RDONLY) {
|
||||
if (env->me_txn0 &&
|
||||
unlikely(env->me_txn0->mt_owner == mdbx_thread_self()) &&
|
||||
(mdbx_runtime_flags & MDBX_DBG_LEGACY_OVERLAP) == 0)
|
||||
@ -6466,7 +6467,7 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags,
|
||||
rc = mdbx_cursor_shadow(parent, txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
mdbx_txn_end(txn, MDBX_END_FAIL_BEGINCHILD);
|
||||
} else { /* MDBX_RDONLY */
|
||||
} else { /* MDBX_TXN_RDONLY */
|
||||
txn->mt_dbiseqs = env->me_dbiseqs;
|
||||
renew:
|
||||
rc = mdbx_txn_renew0(txn, flags);
|
||||
@ -6477,15 +6478,15 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags,
|
||||
mdbx_free(txn);
|
||||
} else {
|
||||
mdbx_assert(env,
|
||||
(txn->mt_flags & ~(MDBX_NOTLS | MDBX_RDONLY | MDBX_WRITEMAP |
|
||||
MDBX_SHRINK_ALLOWED | MDBX_NOMETASYNC |
|
||||
MDBX_SAFE_NOSYNC)) == 0);
|
||||
(txn->mt_flags & ~(MDBX_NOTLS | MDBX_TXN_RDONLY |
|
||||
MDBX_WRITEMAP | MDBX_SHRINK_ALLOWED |
|
||||
MDBX_NOMETASYNC | MDBX_SAFE_NOSYNC)) == 0);
|
||||
txn->mt_signature = MDBX_MT_SIGNATURE;
|
||||
*ret = txn;
|
||||
mdbx_debug("begin txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO
|
||||
"/%" PRIaPGNO,
|
||||
txn->mt_txnid, (flags & MDBX_RDONLY) ? 'r' : 'w', (void *)txn,
|
||||
(void *)env, txn->mt_dbs[MAIN_DBI].md_root,
|
||||
txn->mt_txnid, (flags & MDBX_TXN_RDONLY) ? 'r' : 'w',
|
||||
(void *)txn, (void *)env, txn->mt_dbs[MAIN_DBI].md_root,
|
||||
txn->mt_dbs[FREE_DBI].md_root);
|
||||
}
|
||||
|
||||
@ -6511,7 +6512,7 @@ int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, bool scan_rlt) {
|
||||
info->txn_id = txn->mt_txnid;
|
||||
info->txn_space_used = pgno2bytes(env, txn->mt_geo.next);
|
||||
|
||||
if (txn->mt_flags & MDBX_RDONLY) {
|
||||
if (txn->mt_flags & MDBX_TXN_RDONLY) {
|
||||
const MDBX_meta *head_meta;
|
||||
txnid_t head_txnid;
|
||||
uint64_t head_retired;
|
||||
@ -6682,7 +6683,7 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
||||
mdbx_debug("%s txn %" PRIaTXN "%c %p on mdbenv %p, root page %" PRIaPGNO
|
||||
"/%" PRIaPGNO,
|
||||
names[mode & MDBX_END_OPMASK], txn->mt_txnid,
|
||||
(txn->mt_flags & MDBX_RDONLY) ? 'r' : 'w', (void *)txn,
|
||||
(txn->mt_flags & MDBX_TXN_RDONLY) ? 'r' : 'w', (void *)txn,
|
||||
(void *)env, txn->mt_dbs[MAIN_DBI].md_root,
|
||||
txn->mt_dbs[FREE_DBI].md_root);
|
||||
|
||||
@ -6690,7 +6691,7 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
||||
/* paranoia is appropriate here */ *env->me_oldest);
|
||||
|
||||
int rc = MDBX_SUCCESS;
|
||||
if (F_ISSET(txn->mt_flags, MDBX_RDONLY)) {
|
||||
if (F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)) {
|
||||
if (txn->to.reader) {
|
||||
MDBX_reader *slot = txn->to.reader;
|
||||
mdbx_assert(env, slot->mr_pid == env->me_pid);
|
||||
@ -6721,7 +6722,7 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
||||
mdbx_srwlock_ReleaseShared(&env->me_remap_guard);
|
||||
#endif
|
||||
txn->mt_numdbs = 0; /* prevent further DBI activity */
|
||||
txn->mt_flags = MDBX_RDONLY | MDBX_TXN_FINISHED;
|
||||
txn->mt_flags = MDBX_TXN_RDONLY | MDBX_TXN_FINISHED;
|
||||
txn->mt_owner = 0;
|
||||
} else if (!F_ISSET(txn->mt_flags, MDBX_TXN_FINISHED)) {
|
||||
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||
@ -6814,7 +6815,7 @@ int mdbx_txn_reset(MDBX_txn *txn) {
|
||||
return rc;
|
||||
|
||||
/* This call is only valid for read-only txns */
|
||||
if (unlikely((txn->mt_flags & MDBX_RDONLY) == 0))
|
||||
if (unlikely((txn->mt_flags & MDBX_TXN_RDONLY) == 0))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
/* LY: don't close DBI-handles */
|
||||
@ -6831,7 +6832,7 @@ int mdbx_txn_abort(MDBX_txn *txn) {
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
|
||||
if (F_ISSET(txn->mt_flags, MDBX_RDONLY))
|
||||
if (F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY))
|
||||
/* LY: don't close DBI-handles */
|
||||
return mdbx_txn_end(txn, MDBX_END_ABORT | MDBX_END_UPDATE | MDBX_END_SLOT |
|
||||
MDBX_END_FREE);
|
||||
@ -6848,7 +6849,7 @@ int mdbx_txn_abort(MDBX_txn *txn) {
|
||||
static __cold int mdbx_audit_ex(MDBX_txn *txn, unsigned retired_stored,
|
||||
bool dont_filter_gc) {
|
||||
pgno_t pending = 0;
|
||||
if ((txn->mt_flags & MDBX_RDONLY) == 0) {
|
||||
if ((txn->mt_flags & MDBX_TXN_RDONLY) == 0) {
|
||||
pending = txn->tw.loose_count + MDBX_PNL_SIZE(txn->tw.reclaimed_pglist) +
|
||||
(MDBX_PNL_SIZE(txn->tw.retired_pages) - retired_stored) +
|
||||
txn->tw.retired2parent_count;
|
||||
@ -6909,7 +6910,7 @@ static __cold int mdbx_audit_ex(MDBX_txn *txn, unsigned retired_stored,
|
||||
return MDBX_CORRUPTED;
|
||||
MDBX_db db_copy, *db;
|
||||
memcpy(db = &db_copy, node_data(node), sizeof(db_copy));
|
||||
if ((txn->mt_flags & MDBX_RDONLY) == 0) {
|
||||
if ((txn->mt_flags & MDBX_TXN_RDONLY) == 0) {
|
||||
for (MDBX_dbi k = txn->mt_numdbs; --k > MAIN_DBI;) {
|
||||
if ((txn->mt_dbistate[k] & DBI_VALID) &&
|
||||
/* txn->mt_dbxs[k].md_name.iov_len > 0 && */
|
||||
@ -6954,7 +6955,7 @@ static __cold int mdbx_audit_ex(MDBX_txn *txn, unsigned retired_stored,
|
||||
if (pending + freecount + count + NUM_METAS == txn->mt_next_pgno)
|
||||
return MDBX_SUCCESS;
|
||||
|
||||
if ((txn->mt_flags & MDBX_RDONLY) == 0)
|
||||
if ((txn->mt_flags & MDBX_TXN_RDONLY) == 0)
|
||||
mdbx_error("audit @%" PRIaTXN ": %u(pending) = %u(loose-count) + "
|
||||
"%u(reclaimed-list) + %u(retired-pending) - %u(retired-stored) "
|
||||
"+ %u(retired2parent)",
|
||||
@ -7875,7 +7876,7 @@ int mdbx_txn_commit(MDBX_txn *txn) {
|
||||
/* mdbx_txn_end() mode for a commit which writes nothing */
|
||||
unsigned end_mode =
|
||||
MDBX_END_EMPTY_COMMIT | MDBX_END_UPDATE | MDBX_END_SLOT | MDBX_END_FREE;
|
||||
if (unlikely(F_ISSET(txn->mt_flags, MDBX_RDONLY)))
|
||||
if (unlikely(F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)))
|
||||
goto done;
|
||||
|
||||
if (txn->mt_child) {
|
||||
@ -10827,11 +10828,11 @@ __hot static int mdbx_page_get(MDBX_cursor *mc, pgno_t pgno, MDBX_page **ret,
|
||||
MDBX_page *p = NULL;
|
||||
int level;
|
||||
mdbx_assert(env, ((txn->mt_flags ^ env->me_flags) & MDBX_WRITEMAP) == 0);
|
||||
const uint16_t illegal_bits = (txn->mt_flags & MDBX_RDONLY)
|
||||
const uint16_t illegal_bits = (txn->mt_flags & MDBX_TXN_RDONLY)
|
||||
? P_LOOSE | P_SUBP | P_META | P_DIRTY
|
||||
: P_LOOSE | P_SUBP | P_META;
|
||||
const uint64_t txnid = txn->mt_txnid;
|
||||
if (unlikely((txn->mt_flags & (MDBX_RDONLY | MDBX_WRITEMAP)) == 0)) {
|
||||
if (unlikely((txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_WRITEMAP)) == 0)) {
|
||||
level = 1;
|
||||
do {
|
||||
/* Spilled pages were dirtied in this txn and flushed
|
||||
@ -12073,8 +12074,9 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
|
||||
nospill = flags & MDBX_NOSPILL;
|
||||
flags &= ~MDBX_NOSPILL;
|
||||
|
||||
if (unlikely(mc->mc_txn->mt_flags & (MDBX_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (mc->mc_txn->mt_flags & MDBX_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
if (unlikely(mc->mc_txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (mc->mc_txn->mt_flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
|
||||
: MDBX_BAD_TXN;
|
||||
|
||||
uint64_t aligned_keybytes, aligned_databytes;
|
||||
MDBX_val aligned_key, aligned_data;
|
||||
@ -13383,7 +13385,7 @@ int mdbx_cursor_open(MDBX_txn *txn, MDBX_dbi dbi, MDBX_cursor **ret) {
|
||||
if (unlikely(!mdbx_txn_dbi_exists(txn, dbi, DBI_VALID)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(dbi == FREE_DBI && !F_ISSET(txn->mt_flags, MDBX_RDONLY)))
|
||||
if (unlikely(dbi == FREE_DBI && !F_ISSET(txn->mt_flags, MDBX_TXN_RDONLY)))
|
||||
return MDBX_EACCESS;
|
||||
|
||||
const size_t size = (txn->mt_dbs[dbi].md_flags & MDBX_DUPSORT)
|
||||
@ -14901,8 +14903,8 @@ int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
if (unlikely(!mdbx_txn_dbi_exists(txn, dbi, DBI_USRVALID)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(txn->mt_flags & (MDBX_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
|
||||
return mdbx_del0(txn, dbi, key, data, 0);
|
||||
}
|
||||
@ -15447,8 +15449,8 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data,
|
||||
MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(txn->mt_flags & (MDBX_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
|
||||
MDBX_cursor_couple cx;
|
||||
rc = mdbx_cursor_init(&cx.outer, txn, dbi);
|
||||
@ -15923,7 +15925,7 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
|
||||
rc = mdbx_txn_renew0(read_txn, MDBX_RDONLY);
|
||||
rc = mdbx_txn_renew0(read_txn, MDBX_TXN_RDONLY);
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
mdbx_txn_unlock(env);
|
||||
return rc;
|
||||
@ -16040,7 +16042,7 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
||||
MDBX_txn *read_txn = NULL;
|
||||
/* Do the lock/unlock of the reader mutex before starting the
|
||||
* write txn. Otherwise other read txns could block writers. */
|
||||
rc = mdbx_txn_begin(env, NULL, MDBX_RDONLY, &read_txn);
|
||||
rc = mdbx_txn_begin(env, NULL, MDBX_TXN_RDONLY, &read_txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
mdbx_memalign_free(buffer);
|
||||
return rc;
|
||||
@ -16371,7 +16373,7 @@ int __cold mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
|
||||
arg->mi_last_pgno = txn->mt_next_pgno - 1;
|
||||
arg->mi_geo.current = pgno2bytes(env, txn->mt_end_pgno);
|
||||
|
||||
const txnid_t wanna_meta_txnid = (txn->mt_flags & MDBX_RDONLY)
|
||||
const txnid_t wanna_meta_txnid = (txn->mt_flags & MDBX_TXN_RDONLY)
|
||||
? txn->mt_txnid
|
||||
: txn->mt_txnid - MDBX_TXNID_STEP;
|
||||
txn_meta = (arg->mi_meta0_txnid == wanna_meta_txnid) ? meta0 : txn_meta;
|
||||
@ -16473,7 +16475,7 @@ static int mdbx_dbi_bind(MDBX_txn *txn, const MDBX_dbi dbi, unsigned user_flags,
|
||||
* seems that is case #1 above */
|
||||
user_flags = txn->mt_dbs[dbi].md_flags;
|
||||
} else if ((user_flags & MDBX_CREATE) && txn->mt_dbs[dbi].md_entries == 0) {
|
||||
if (txn->mt_flags & MDBX_RDONLY)
|
||||
if (txn->mt_flags & MDBX_TXN_RDONLY)
|
||||
return /* FIXME: return extended info */ MDBX_EACCESS;
|
||||
/* make sure flags changes get committed */
|
||||
txn->mt_dbs[dbi].md_flags = user_flags & DB_PERSISTENT_FLAGS;
|
||||
@ -16617,7 +16619,7 @@ static int dbi_open(MDBX_txn *txn, const char *table_name, unsigned user_flags,
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != MDBX_SUCCESS && unlikely(txn->mt_flags & MDBX_RDONLY)) {
|
||||
if (rc != MDBX_SUCCESS && unlikely(txn->mt_flags & MDBX_TXN_RDONLY)) {
|
||||
rc = MDBX_EACCESS;
|
||||
goto early_bailout;
|
||||
}
|
||||
@ -17399,7 +17401,7 @@ int mdbx_txn_straggler(const MDBX_txn *txn, int *percent)
|
||||
return (rc > 0) ? -rc : rc;
|
||||
|
||||
MDBX_env *env = txn->mt_env;
|
||||
if (unlikely((txn->mt_flags & MDBX_RDONLY) == 0)) {
|
||||
if (unlikely((txn->mt_flags & MDBX_TXN_RDONLY) == 0)) {
|
||||
if (percent)
|
||||
*percent =
|
||||
(int)((txn->mt_next_pgno * UINT64_C(100) + txn->mt_end_pgno / 2) /
|
||||
@ -18372,7 +18374,7 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
|
||||
if (txn->mt_flags & MDBX_RDONLY)
|
||||
if (txn->mt_flags & MDBX_TXN_RDONLY)
|
||||
return MDBX_RESULT_FALSE;
|
||||
|
||||
const MDBX_env *env = txn->mt_env;
|
||||
@ -18443,7 +18445,7 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
|
||||
*result = dbs->md_seq;
|
||||
|
||||
if (likely(increment > 0)) {
|
||||
if (unlikely(txn->mt_flags & MDBX_RDONLY))
|
||||
if (unlikely(txn->mt_flags & MDBX_TXN_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
|
||||
uint64_t new = dbs->md_seq + increment;
|
||||
@ -18819,8 +18821,8 @@ int mdbx_set_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data,
|
||||
if (unlikely(!TXN_DBI_EXIST(txn, dbi, DB_USRVALID)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(txn->mt_flags & (MDBX_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
if (unlikely(txn->mt_flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->mt_flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
|
||||
MDBX_cursor_couple cx;
|
||||
MDBX_val old_data;
|
||||
|
@ -721,8 +721,7 @@ struct MDBX_txn {
|
||||
/* Transaction Flags */
|
||||
/* mdbx_txn_begin() flags */
|
||||
#define MDBX_TXN_BEGIN_FLAGS \
|
||||
(MDBX_NOMETASYNC | MDBX_SAFE_NOSYNC | MDBX_MAPASYNC | MDBX_RDONLY | \
|
||||
MDBX_TRYTXN)
|
||||
(MDBX_TXN_NOMETASYNC | MDBX_TXN_NOSYNC | MDBX_TXN_RDONLY | MDBX_TXN_TRY)
|
||||
/* Additional flag for mdbx_sync_locked() */
|
||||
#define MDBX_SHRINK_ALLOWED UINT32_C(0x40000000)
|
||||
|
||||
|
@ -1071,7 +1071,7 @@ int main(int argc, char *argv[]) {
|
||||
locked = true;
|
||||
}
|
||||
|
||||
rc = mdbx_txn_begin(env, nullptr, MDBX_RDONLY, &txn);
|
||||
rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
|
||||
if (rc) {
|
||||
error("mdbx_txn_begin() failed, error %d %s\n", rc, mdbx_strerror(rc));
|
||||
goto bailout;
|
||||
|
@ -8,11 +8,11 @@ bool testcase_try::run() {
|
||||
MDBX_txn *txn2 = nullptr;
|
||||
int rc = mdbx_txn_begin(db_guard.get(), nullptr, 0, &txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
failure_perror("mdbx_txn_begin(MDBX_TRYTXN)", rc);
|
||||
failure_perror("mdbx_txn_begin(MDBX_TXN_TRY)", rc);
|
||||
else {
|
||||
rc = mdbx_txn_begin(db_guard.get(), nullptr, MDBX_TRYTXN, &txn2);
|
||||
rc = mdbx_txn_begin(db_guard.get(), nullptr, MDBX_TXN_TRY, &txn2);
|
||||
if (unlikely(rc != MDBX_BUSY))
|
||||
failure_perror("mdbx_txn_begin(MDBX_TRYTXN)", rc);
|
||||
failure_perror("mdbx_txn_begin(MDBX_TXN_TRY)", rc);
|
||||
}
|
||||
|
||||
txn_guard.reset(txn);
|
||||
|
Loading…
x
Reference in New Issue
Block a user