mdbx: возможность логирования ошибок возвращаемых из API (return LOG_IFERR).

Возможность полезная, но пожалуй еще нуждается в доработке и/или
до-осмыслении. Основное неудобство в нестыковке с основным логированием.

С одной стороны, сообщение об ошибках следует выводить с
уровнем/severity MDBX_LOG_ERROR. Однако, это замусоривает и ломает
тесты.

Поэтому сейчас при возвращении ошибок из API сообщения логируются
MDBX_LOG_ERROR, но производится это только при включении уровня
логирования MDBX_LOG_DEBUG или более детальном.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-11-25 21:20:02 +03:00
parent 9daff17c82
commit 28bd805ed8
15 changed files with 433 additions and 389 deletions

View File

@ -29,16 +29,16 @@ MDBX_cursor *mdbx_cursor_create(void *context) {
int mdbx_cursor_renew(const MDBX_txn *txn, MDBX_cursor *mc) {
return likely(mc)
? mdbx_cursor_bind(txn, mc, (kvx_t *)mc->clc - txn->env->kvs)
: MDBX_EINVAL;
: LOG_IFERR(MDBX_EINVAL);
}
int mdbx_cursor_reset(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
cursor_couple_t *couple = (cursor_couple_t *)mc;
couple->outer.top_and_flags = z_poor_mark;
@ -48,29 +48,29 @@ int mdbx_cursor_reset(MDBX_cursor *mc) {
int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(dbi == FREE_DBI && !(txn->flags & MDBX_TXN_RDONLY)))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(mc->backup)) /* Cursor from parent transaction */ {
cASSERT(mc, mc->signature == cur_signature_live);
if (unlikely(cursor_dbi(mc) != dbi ||
/* paranoia */ mc->signature != cur_signature_live ||
mc->txn != txn))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cASSERT(mc, mc->tree == &txn->dbs[dbi]);
cASSERT(mc, mc->clc == &txn->env->kvs[dbi].clc);
@ -79,7 +79,9 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
/* paranoia */ mc->signature == cur_signature_live &&
mc->txn == txn)
? MDBX_SUCCESS
: MDBX_EINVAL /* Disallow change DBI in nested transactions */;
: LOG_IFERR(MDBX_EINVAL) /* Disallow change DBI in nested
transactions */
;
}
if (mc->signature == cur_signature_live) {
@ -91,7 +93,7 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
rc = cursor_init(mc, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
mc->next = txn->cursors[dbi];
txn->cursors[dbi] = mc;
@ -100,14 +102,15 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
int mdbx_cursor_unbind(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_SUCCESS
: MDBX_EBADSIGN;
return (mc->signature == cur_signature_ready4dispose)
? MDBX_SUCCESS
: LOG_IFERR(MDBX_EBADSIGN);
if (unlikely(mc->backup)) /* Cursor from parent transaction */
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
eASSERT(nullptr, mc->txn && mc->txn->signature == txn_signature);
cASSERT(mc, mc->signature == cur_signature_live);
@ -116,7 +119,7 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
ERROR("Wrong cursor's transaction %p 0x%x",
__Wpedantic_format_voidptr(mc->txn),
mc->txn ? mc->txn->signature : 0);
return MDBX_PROBLEM;
return LOG_IFERR(MDBX_PROBLEM);
}
if (mc->next != mc) {
const size_t dbi = (kvx_t *)mc->clc - mc->txn->env->kvs;
@ -138,17 +141,17 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
int mdbx_cursor_open(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_cursor **ret) {
if (unlikely(!ret))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*ret = nullptr;
MDBX_cursor *const mc = mdbx_cursor_create(nullptr);
if (unlikely(!mc))
return MDBX_ENOMEM;
return LOG_IFERR(MDBX_ENOMEM);
int rc = mdbx_cursor_bind(txn, mc, dbi);
if (unlikely(rc != MDBX_SUCCESS)) {
mdbx_cursor_close(mc);
return rc;
return LOG_IFERR(rc);
}
*ret = mc;
@ -189,10 +192,11 @@ void mdbx_cursor_close(MDBX_cursor *mc) {
int mdbx_cursor_copy(const MDBX_cursor *src, MDBX_cursor *dest) {
if (unlikely(!src))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(src->signature != cur_signature_live))
return (src->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((src->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = mdbx_cursor_bind(src->txn, dest, cursor_dbi(src));
if (unlikely(rc != MDBX_SUCCESS))
@ -241,6 +245,7 @@ int mdbx_txn_release_all_cursors(const MDBX_txn *txn, bool unbind) {
}
} else {
eASSERT(nullptr, rc < 0);
LOG_IFERR(rc);
}
return rc;
}
@ -325,18 +330,19 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r,
/* Return the count of duplicate data items for the current key */
int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(countp == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if ((*countp = is_filled(mc)) > 0) {
if (!inner_hollow(mc)) {
@ -353,11 +359,12 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
int mdbx_cursor_on_first(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
for (intptr_t i = 0; i <= mc->top; ++i) {
if (mc->ki[i])
@ -369,11 +376,12 @@ int mdbx_cursor_on_first(const MDBX_cursor *mc) {
int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
if (is_filled(mc) && mc->subcur) {
mc = &mc->subcur->cursor;
@ -388,11 +396,12 @@ int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
int mdbx_cursor_on_last(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
for (intptr_t i = 0; i <= mc->top; ++i) {
size_t nkeys = page_numkeys(mc->pg[i]);
@ -405,11 +414,12 @@ int mdbx_cursor_on_last(const MDBX_cursor *mc) {
int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
if (is_filled(mc) && mc->subcur) {
mc = &mc->subcur->cursor;
@ -425,11 +435,12 @@ int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
int mdbx_cursor_eof(const MDBX_cursor *mc) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
return is_eof(mc) ? MDBX_RESULT_TRUE : MDBX_RESULT_FALSE;
}
@ -437,20 +448,21 @@ int mdbx_cursor_eof(const MDBX_cursor *mc) {
int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
MDBX_cursor_op op) {
if (unlikely(mc == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
return cursor_ops(mc, key, data, op);
return LOG_IFERR(cursor_ops(mc, key, data, op));
}
__hot static int scan_confinue(MDBX_cursor *mc, MDBX_predicate_func *predicate,
@ -520,33 +532,34 @@ int mdbx_cursor_scan(MDBX_cursor *mc, MDBX_predicate_func *predicate,
void *context, MDBX_cursor_op start_op,
MDBX_cursor_op turn_op, void *arg) {
if (unlikely(!predicate))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_start_mask =
1 << MDBX_FIRST | 1 << MDBX_FIRST_DUP | 1 << MDBX_LAST |
1 << MDBX_LAST_DUP | 1 << MDBX_GET_CURRENT | 1 << MDBX_GET_MULTIPLE;
if (unlikely(start_op > 30 || ((1 << start_op) & valid_start_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_turn_mask =
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
MDBX_val key = {nullptr, 0}, value = {nullptr, 0};
int rc = mdbx_cursor_get(mc, &key, &value, start_op);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return scan_confinue(mc, predicate, context, arg, &key, &value, turn_op);
return LOG_IFERR(rc);
return LOG_IFERR(
scan_confinue(mc, predicate, context, arg, &key, &value, turn_op));
}
int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
void *context, MDBX_cursor_op from_op, MDBX_val *key,
MDBX_val *value, MDBX_cursor_op turn_op, void *arg) {
if (unlikely(!predicate || !key))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_start_mask =
1 << MDBX_GET_BOTH | 1 << MDBX_GET_BOTH_RANGE | 1 << MDBX_SET_KEY |
@ -554,18 +567,18 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
1 << MDBX_SET_UPPERBOUND;
if (unlikely(from_op < MDBX_TO_KEY_LESSER_THAN &&
((1 << from_op) & valid_start_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const unsigned valid_turn_mask =
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = mdbx_cursor_get(mc, key, value, from_op);
if (unlikely(MDBX_IS_ERROR(rc)))
return rc;
return LOG_IFERR(rc);
cASSERT(mc, key != nullptr);
MDBX_val stub;
@ -573,51 +586,53 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
value = &stub;
rc = cursor_ops(mc, key, value, MDBX_GET_CURRENT);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
return scan_confinue(mc, predicate, context, arg, key, value, turn_op);
return LOG_IFERR(
scan_confinue(mc, predicate, context, arg, key, value, turn_op));
}
int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
size_t limit, MDBX_cursor_op op) {
if (unlikely(!count))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*count = 0;
if (unlikely(mc == nullptr || limit < 4 || limit > INTPTR_MAX - 2))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(mc->subcur))
return MDBX_INCOMPATIBLE /* must be a non-dupsort table */;
return LOG_IFERR(MDBX_INCOMPATIBLE) /* must be a non-dupsort table */;
switch (op) {
case MDBX_NEXT:
if (unlikely(is_eof(mc)))
return is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA;
return LOG_IFERR(is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA);
break;
case MDBX_FIRST:
if (!is_filled(mc)) {
rc = outer_first(mc, nullptr, nullptr);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
break;
default:
DEBUG("unhandled/unimplemented cursor operation %u", op);
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
}
const page_t *mp = mc->pg[mc->top];
@ -662,18 +677,18 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
bailout:
*count = n;
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
int mdbx_cursor_set_userctx(MDBX_cursor *mc, void *ctx) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_ready4dispose &&
mc->signature != cur_signature_live))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
cursor_couple_t *couple = container_of(mc, cursor_couple_t, outer);
couple->userctx = ctx;
@ -714,80 +729,84 @@ MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *mc) {
int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
MDBX_put_flags_t flags) {
if (unlikely(mc == nullptr || key == nullptr || data == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
cASSERT(mc, cursor_is_tracked(mc));
/* Check this first so counter will always be zero on any early failures. */
if (unlikely(flags & MDBX_MULTIPLE)) {
if (unlikely(flags & MDBX_RESERVE))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(!(mc->tree->flags & MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
const size_t dcount = data[1].iov_len;
if (unlikely(dcount < 2 || data->iov_len == 0))
return MDBX_BAD_VALSIZE;
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(mc->tree->dupfix_size != data->iov_len) &&
mc->tree->dupfix_size)
return MDBX_BAD_VALSIZE;
return LOG_IFERR(MDBX_BAD_VALSIZE);
if (unlikely(dcount >
MAX_MAPSIZE / 2 /
(BRANCH_NODE_MAX(MDBX_MAX_PAGESIZE) - NODESIZE))) {
/* checking for multiplication overflow */
if (unlikely(dcount > MAX_MAPSIZE / 2 / data->iov_len))
return MDBX_TOO_LARGE;
return LOG_IFERR(MDBX_TOO_LARGE);
}
}
if (flags & MDBX_RESERVE) {
if (unlikely(mc->tree->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP |
MDBX_INTEGERDUP | MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
data->iov_base = nullptr;
}
if (unlikely(mc->txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
return (mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
return LOG_IFERR((mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
: MDBX_BAD_TXN);
return cursor_put_checklen(mc, key, data, flags);
return LOG_IFERR(cursor_put_checklen(mc, key, data, flags));
}
int mdbx_cursor_del(MDBX_cursor *mc, MDBX_put_flags_t flags) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(cursor_dbi_changed(mc)))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
return cursor_del(mc, flags);
return LOG_IFERR(cursor_del(mc, flags));
}
__cold int mdbx_cursor_ignord(MDBX_cursor *mc) {
if (unlikely(!mc))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(mc->signature != cur_signature_live))
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
mc->checking |= z_ignord;
if (mc->subcur)

View File

@ -196,18 +196,18 @@ __cold static int env_handle_pathname(MDBX_env *env, const pathchar_t *pathname,
__cold int mdbx_env_create(MDBX_env **penv) {
if (unlikely(!penv))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*penv = nullptr;
#ifdef MDBX_HAVE_C11ATOMICS
if (unlikely(!atomic_is_lock_free((const volatile uint32_t *)penv))) {
ERROR("lock-free atomic ops for %u-bit types is required", 32);
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
}
#if MDBX_64BIT_ATOMIC
if (unlikely(!atomic_is_lock_free((const volatile uint64_t *)penv))) {
ERROR("lock-free atomic ops for %u-bit types is required", 64);
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
}
#endif /* MDBX_64BIT_ATOMIC */
#endif /* MDBX_HAVE_C11ATOMICS */
@ -215,25 +215,25 @@ __cold int mdbx_env_create(MDBX_env **penv) {
if (unlikely(!is_powerof2(globals.sys_pagesize) ||
globals.sys_pagesize < MDBX_MIN_PAGESIZE)) {
ERROR("unsuitable system pagesize %u", globals.sys_pagesize);
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
}
#if defined(__linux__) || defined(__gnu_linux__)
if (unlikely(globals.linux_kernel_version < 0x04000000)) {
/* 2022-09-01: Прошло уже больше двух после окончания какой-либо поддержки
* самого "долгоиграющего" ядра 3.16.85 ветки 3.x */
/* 2022-09-01: Прошло уже более двух лет после окончания какой-либо
* поддержки самого "долгоиграющего" ядра 3.16.85 ветки 3.x */
ERROR("too old linux kernel %u.%u.%u.%u, the >= 4.0.0 is required",
globals.linux_kernel_version >> 24,
(globals.linux_kernel_version >> 16) & 255,
(globals.linux_kernel_version >> 8) & 255,
globals.linux_kernel_version & 255);
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
}
#endif /* Linux */
MDBX_env *env = osal_calloc(1, sizeof(MDBX_env));
if (unlikely(!env))
return MDBX_ENOMEM;
return LOG_IFERR(MDBX_ENOMEM);
env->max_readers = DEFAULT_READERS;
env->max_dbi = env->n_dbi = CORE_DBS;
@ -278,18 +278,18 @@ __cold int mdbx_env_create(MDBX_env **penv) {
bailout:
osal_free(env);
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
if (unlikely(target >= NUM_METAS))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely((env->flags & (MDBX_EXCLUSIVE | MDBX_RDONLY)) != MDBX_EXCLUSIVE))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
const meta_t *const target_meta = METAPAGE(env, target);
txnid_t new_txnid = constmeta_txnid(target_meta);
@ -303,7 +303,7 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
if (meta_validate(env, &meta, page, n, nullptr) != MDBX_SUCCESS) {
int err = meta_override(env, n, 0, nullptr);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
} else {
txnid_t txnid = constmeta_txnid(&meta);
if (new_txnid <= txnid)
@ -313,9 +313,9 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
if (unlikely(new_txnid > MAX_TXNID)) {
ERROR("txnid overflow, raise %d", MDBX_TXN_FULL);
return MDBX_TXN_FULL;
return LOG_IFERR(MDBX_TXN_FULL);
}
return meta_override(env, target, new_txnid, target_meta);
return LOG_IFERR(meta_override(env, target, new_txnid, target_meta));
}
__cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
@ -327,7 +327,7 @@ __cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
rc = mdbx_env_open_for_recoveryW(env, pathnameW, target_meta, writeable);
osal_free(pathnameW);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_open_for_recoveryW(MDBX_env *env, const wchar_t *pathname,
@ -335,12 +335,12 @@ __cold int mdbx_env_open_for_recoveryW(MDBX_env *env, const wchar_t *pathname,
#endif /* Windows */
if (unlikely(target_meta >= NUM_METAS))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(env->dxb_mmap.base))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
env->stuck_meta = (int8_t)target_meta;
return
@ -361,7 +361,7 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
rc = mdbx_env_deleteW(pathnameW, mode);
osal_free(pathnameW);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_deleteW(const wchar_t *pathname,
@ -370,7 +370,7 @@ __cold int mdbx_env_deleteW(const wchar_t *pathname,
switch (mode) {
default:
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
case MDBX_ENV_JUST_DELETE:
case MDBX_ENV_ENSURE_UNUSED:
case MDBX_ENV_WAIT_FOR_UNUSED:
@ -442,7 +442,7 @@ __cold int mdbx_env_deleteW(const wchar_t *pathname,
err = MDBX_SUCCESS;
osal_free(dummy_env->pathname.buffer);
return (err == MDBX_SUCCESS) ? rc : err;
return LOG_IFERR((err == MDBX_SUCCESS) ? rc : err);
}
__cold int mdbx_env_open(MDBX_env *env, const char *pathname,
@ -457,7 +457,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
/* force to make cache of the multi-byte pathname representation */
mdbx_env_get_path(env, &pathname);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
@ -466,14 +466,14 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(flags & ~ENV_USABLE_FLAGS))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->lazy_fd != INVALID_HANDLE_VALUE ||
(env->flags & ENV_ACTIVE) != 0 || env->dxb_mmap.base))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
/* Pickup previously mdbx_env_set_flags(),
* but avoid MDBX_UTTERLY_NOSYNC by disjunction */
@ -497,7 +497,7 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
debug_log(MDBX_LOG_ERROR, __func__, __LINE__,
"System (i.e. OpenBSD) requires MDBX_WRITEMAP because "
"of an internal flaw(s) in a file/buffer/page cache.\n");
return 42 /* ENOPROTOOPT */;
return LOG_IFERR(42 /* ENOPROTOOPT */);
}
}
#endif /* MDBX_MMAP_INCOHERENT_FILE_WRITE */
@ -590,7 +590,7 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
env->flags = saved_me_flags | ENV_FATAL_ERROR;
}
}
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
@ -598,13 +598,13 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
#if !(defined(_WIN32) || defined(_WIN64))
__cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
if (unlikely(!env))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->signature.weak != env_signature))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
if (unlikely(env->flags & ENV_FATAL_ERROR))
return MDBX_PANIC;
return LOG_IFERR(MDBX_PANIC);
if (unlikely((env->flags & ENV_ACTIVE) == 0))
return MDBX_SUCCESS;
@ -614,7 +614,7 @@ __cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
return MDBX_SUCCESS;
if (!atomic_cas32(&env->signature, env_signature, ~env_signature))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
if (env->txn)
txn_abort(env->basal_txn);
@ -628,7 +628,7 @@ __cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
env->flags |= ENV_FATAL_ERROR;
}
}
return rc;
return LOG_IFERR(rc);
}
#endif /* Windows */
@ -637,10 +637,10 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
int rc = MDBX_SUCCESS;
if (unlikely(!env))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->signature.weak != env_signature))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
#if MDBX_ENV_CHECKPID || !(defined(_WIN32) || defined(_WIN64))
/* Check the PID even if MDBX_ENV_CHECKPID=0 on non-Windows
@ -654,12 +654,12 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
if (env->dxb_mmap.base &&
(env->flags & (MDBX_RDONLY | ENV_FATAL_ERROR)) == 0 && env->basal_txn) {
if (env->basal_txn->owner && env->basal_txn->owner != osal_thread_self())
return MDBX_BUSY;
return LOG_IFERR(MDBX_BUSY);
} else
dont_sync = true;
if (!atomic_cas32(&env->signature, env_signature, 0))
return MDBX_EBADSIGN;
return LOG_IFERR(MDBX_EBADSIGN);
if (!dont_sync) {
#if defined(_WIN32) || defined(_WIN64)
@ -712,7 +712,7 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
VALGRIND_DESTROY_MEMPOOL(env);
osal_free(env);
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
@ -889,32 +889,32 @@ __cold int env_info(const MDBX_env *env, const MDBX_txn *txn, MDBX_envinfo *out,
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_envinfo *arg, size_t bytes) {
if (unlikely((env == nullptr && txn == nullptr) || arg == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid);
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
bytes != size_before_pgop_stat && bytes != size_before_dxbid)
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (txn) {
int err = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
}
if (env) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
if (txn && unlikely(txn->env != env))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
} else {
env = txn->env;
}
troika_t troika;
return env_info(env, txn, arg, bytes, &troika);
return LOG_IFERR(env_info(env, txn, arg, bytes, &troika));
}
__cold int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *out,
@ -926,21 +926,21 @@ __cold int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *out,
rc = mdbx_preopen_snapinfoW(pathnameW, out, bytes);
osal_free(pathnameW);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
size_t bytes) {
#endif /* Windows */
if (unlikely(!out))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid);
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
bytes != size_before_pgop_stat && bytes != size_before_dxbid)
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
memset(out, 0, bytes);
if (likely(bytes > size_before_bootid)) {
@ -954,7 +954,7 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
if (unlikely(!is_powerof2(globals.sys_pagesize) ||
globals.sys_pagesize < MDBX_MIN_PAGESIZE)) {
ERROR("unsuitable system pagesize %u", globals.sys_pagesize);
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
}
out->mi_sys_pagesize = globals.sys_pagesize;
env.flags = MDBX_RDONLY | MDBX_NORDAHEAD | MDBX_ACCEDE | MDBX_VALIDATION;
@ -1001,7 +1001,7 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
bailout:
env_close(&env, false);
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
@ -1012,7 +1012,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
intptr_t shrink_threshold, intptr_t pagesize) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
const bool txn0_owned = env->basal_txn && env_txn0_owned(env);
const bool inside_txn = txn0_owned && env->txn;
@ -1029,12 +1029,12 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
if (env->dxb_mmap.base) {
/* env already mapped */
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (!txn0_owned) {
int err = lck_txn_lock(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
should_unlock = true;
env->basal_txn->tw.troika = meta_tap(env);
eASSERT(env, !env->txn && !env->basal_txn->nested);
@ -1076,7 +1076,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
} else {
/* env NOT yet mapped */
if (unlikely(inside_txn))
return MDBX_PANIC;
return LOG_IFERR(MDBX_PANIC);
/* is requested some auto-value for pagesize ? */
if (pagesize >= INT_MAX /* maximal */)
@ -1393,13 +1393,13 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
bailout:
if (should_unlock)
lck_txn_unlock(env);
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
return env_sync(env, force, nonblock);
return LOG_IFERR(env_sync(env, force, nonblock));
}

View File

@ -10,10 +10,10 @@ __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func,
void *ctx) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!func))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
rc = MDBX_RESULT_TRUE;
int serial = 0;
@ -74,13 +74,13 @@ __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func,
}
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_reader_check(MDBX_env *env, int *dead) {
if (dead)
*dead = 0;
return mvcc_cleanup_dead(env, false, dead);
return LOG_IFERR(mvcc_cleanup_dead(env, false, dead));
}
/*------------------------------------------------------------------------------
@ -89,28 +89,28 @@ __cold int mdbx_reader_check(MDBX_env *env, int *dead) {
int mdbx_txn_lock(MDBX_env *env, bool dont_wait) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(env->basal_txn->owner ||
(env->basal_txn->flags & MDBX_TXN_FINISHED) == 0))
return MDBX_BUSY;
return LOG_IFERR(MDBX_BUSY);
return lck_txn_lock(env, dont_wait);
return LOG_IFERR(lck_txn_lock(env, dont_wait));
}
int mdbx_txn_unlock(MDBX_env *env) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(env->basal_txn->owner != osal_thread_self()))
return MDBX_THREAD_MISMATCH;
return LOG_IFERR(MDBX_THREAD_MISMATCH);
if (unlikely((env->basal_txn->flags & MDBX_TXN_FINISHED) == 0))
return MDBX_BUSY;
return LOG_IFERR(MDBX_BUSY);
lck_txn_unlock(env);
return MDBX_SUCCESS;

View File

@ -11,7 +11,7 @@ int mdbx_txn_straggler(const MDBX_txn *txn, int *percent)
{
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return (rc > 0) ? -rc : rc;
return LOG_IFERR((rc > 0) ? -rc : rc);
MDBX_env *env = txn->env;
if (unlikely((txn->flags & MDBX_TXN_RDONLY) == 0)) {
@ -42,15 +42,15 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi,
uint32_t *mask) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!mask))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if ((cx.outer.tree->flags & MDBX_DUPSORT) == 0)
return MDBX_RESULT_TRUE;
@ -79,21 +79,21 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi,
default:
ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED,
"invalid node-size", flags);
return MDBX_CORRUPTED;
return LOG_IFERR(MDBX_CORRUPTED);
}
rc = outer_next(&cx.outer, &key, &data, MDBX_NEXT_NODUP);
}
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
return LOG_IFERR((rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc);
}
int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(canary == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*canary = txn->canary;
return MDBX_SUCCESS;
@ -106,37 +106,37 @@ int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key || !data))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
return cursor_seek(&cx.outer, (MDBX_val *)key, data, MDBX_SET).err;
return LOG_IFERR(cursor_seek(&cx.outer, (MDBX_val *)key, data, MDBX_SET).err);
}
int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
MDBX_val *data) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key || !data))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(txn->flags & MDBX_TXN_BLOCKED))
return MDBX_BAD_TXN;
return LOG_IFERR(MDBX_BAD_TXN);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
return cursor_ops(&cx.outer, key, data, MDBX_SET_LOWERBOUND);
return LOG_IFERR(cursor_ops(&cx.outer, key, data, MDBX_SET_LOWERBOUND));
}
int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
@ -146,21 +146,21 @@ int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key || !data))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = cursor_seek(&cx.outer, key, data, MDBX_SET_KEY).err;
if (unlikely(rc != MDBX_SUCCESS)) {
if (values_count)
*values_count = 0;
return rc;
return LOG_IFERR(rc);
}
if (values_count) {
@ -180,7 +180,7 @@ int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (likely(canary)) {
if (txn->canary.x == canary->x && txn->canary.y == canary->y &&
@ -221,7 +221,7 @@ int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary) {
int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
const MDBX_env *env = txn->env;
const ptrdiff_t offset = ptr_dist(ptr, env->dxb_mmap.base);
@ -232,7 +232,7 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
if (unlikely(page->pgno != pgno || (page->flags & P_ILL_BITS) != 0)) {
/* The ptr pointed into middle of a large page,
* not to the beginning of a data. */
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
}
return ((txn->flags & MDBX_TXN_RDONLY) || !is_modifable(txn, page))
? MDBX_RESULT_FALSE
@ -243,7 +243,8 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
* распределенных страниц. Такое может случится если mdbx_is_dirty()
* вызывается после операции, в ходе которой грязная страница была
* возвращена в нераспределенное пространство. */
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EINVAL : MDBX_RESULT_TRUE;
return (txn->flags & MDBX_TXN_RDONLY) ? LOG_IFERR(MDBX_EINVAL)
: MDBX_RESULT_TRUE;
}
}
@ -253,29 +254,31 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
*
* Для режима MDBX_WRITE_MAP режима страница однозначно "не грязная",
* а для режимов без MDBX_WRITE_MAP однозначно "не чистая". */
return (txn->flags & (MDBX_WRITEMAP | MDBX_TXN_RDONLY)) ? MDBX_EINVAL
: MDBX_RESULT_TRUE;
return (txn->flags & (MDBX_WRITEMAP | MDBX_TXN_RDONLY))
? LOG_IFERR(MDBX_EINVAL)
: MDBX_RESULT_TRUE;
}
int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
const MDBX_val *data) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(dbi <= FREE_DBI))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
return LOG_IFERR((txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
: MDBX_BAD_TXN);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
MDBX_val proxy;
MDBX_cursor_op op = MDBX_SET;
@ -288,39 +291,40 @@ int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
}
rc = cursor_seek(&cx.outer, (MDBX_val *)key, (MDBX_val *)data, op).err;
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cx.outer.next = txn->cursors[dbi];
txn->cursors[dbi] = &cx.outer;
rc = cursor_del(&cx.outer, flags);
txn->cursors[dbi] = cx.outer.next;
return rc;
return LOG_IFERR(rc);
}
int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data,
MDBX_put_flags_t flags) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key || !data))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(dbi <= FREE_DBI))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(flags & ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_ALLDUPS |
MDBX_ALLDUPS | MDBX_RESERVE | MDBX_APPEND |
MDBX_APPENDDUP | MDBX_CURRENT | MDBX_MULTIPLE)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
return LOG_IFERR((txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
: MDBX_BAD_TXN);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cx.outer.next = txn->cursors[dbi];
txn->cursors[dbi] = &cx.outer;
@ -348,7 +352,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data,
rc = cursor_put_checklen(&cx.outer, key, data, flags);
txn->cursors[dbi] = cx.outer.next;
return rc;
return LOG_IFERR(rc);
}
//------------------------------------------------------------------------------
@ -383,30 +387,30 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
void *preserver_context) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!key || !old_data || old_data == new_data))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(old_data->iov_base == nullptr && old_data->iov_len))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(new_data == nullptr &&
(flags & (MDBX_CURRENT | MDBX_RESERVE)) != MDBX_CURRENT))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(dbi <= FREE_DBI))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(flags &
~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_ALLDUPS |
MDBX_RESERVE | MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cx.outer.next = txn->cursors[dbi];
txn->cursors[dbi] = &cx.outer;
@ -427,7 +431,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
} else {
/* в old_data буфер для сохранения предыдущего значения */
if (unlikely(new_data && old_data->iov_base == new_data->iov_base))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
MDBX_val present_data;
rc = cursor_seek(&cx.outer, &present_key, &present_data, MDBX_SET_KEY).err;
if (unlikely(rc != MDBX_SUCCESS)) {
@ -485,7 +489,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
bailout:
txn->cursors[dbi] = cx.outer.next;
return rc;
return LOG_IFERR(rc);
}
static int default_value_preserver(void *context, MDBX_val *target,

View File

@ -2019,13 +2019,13 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb,
unsigned timeout_seconds_16dot16) {
int err, rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!cb || !ctx || ctx->internal))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
MDBX_chk_internal_t *const chk = osal_calloc(1, sizeof(MDBX_chk_internal_t));
if (unlikely(!chk))
return MDBX_ENOMEM;
return LOG_IFERR(MDBX_ENOMEM);
chk->cb = cb;
chk->usr = ctx;
@ -2101,5 +2101,5 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb,
err = chk_scope_begin(chk, 0, MDBX_chk_finalize, nullptr, nullptr, nullptr);
rc = chk_scope_end(chk, err ? err : rc);
chk_dispose(chk);
return rc;
return LOG_IFERR(rc);
}

View File

@ -229,35 +229,35 @@ __cold static int stat_acc(const MDBX_txn *txn, MDBX_stat *st, size_t bytes) {
__cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_stat *dest, size_t bytes) {
if (unlikely(!dest))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid);
if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid)
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (likely(txn)) {
if (env && unlikely(txn->env != env))
return MDBX_EINVAL;
return stat_acc(txn, dest, bytes);
return LOG_IFERR(MDBX_EINVAL);
return LOG_IFERR(stat_acc(txn, dest, bytes));
}
int err = check_env(env, true);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
if (env->txn && env_txn0_owned(env))
/* inside write-txn */
return stat_acc(env->txn, dest, bytes);
return LOG_IFERR(stat_acc(env->txn, dest, bytes));
MDBX_txn *tmp_txn;
err = mdbx_txn_begin((MDBX_env *)env, nullptr, MDBX_TXN_RDONLY, &tmp_txn);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
const int rc = stat_acc(tmp_txn, dest, bytes);
err = mdbx_txn_abort(tmp_txn);
if (unlikely(err != MDBX_SUCCESS))
return err;
return rc;
return LOG_IFERR(err);
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
@ -271,23 +271,23 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
MDBX_warmup_flags_t flags,
unsigned timeout_seconds_16dot16) {
if (unlikely(env == nullptr && txn == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(flags >
(MDBX_warmup_force | MDBX_warmup_oomsafe | MDBX_warmup_lock |
MDBX_warmup_touchlimit | MDBX_warmup_release)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (txn) {
int err = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
}
if (env) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
if (txn && unlikely(txn->env != env))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
} else {
env = txn->env;
}
@ -504,7 +504,7 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
#endif
}
return rc;
return LOG_IFERR(rc);
}
/*----------------------------------------------------------------------------*/
@ -512,10 +512,10 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
__cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!arg))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*arg = env->lazy_fd;
return MDBX_SUCCESS;
@ -525,21 +525,21 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
bool onoff) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(flags & ((env->flags & ENV_ACTIVE) ? ~ENV_CHANGEABLE_FLAGS
: ~ENV_USABLE_FLAGS)))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
const bool lock_needed = (env->flags & ENV_ACTIVE) && !env_txn0_owned(env);
bool should_unlock = false;
if (lock_needed) {
rc = lck_txn_lock(env, false);
if (unlikely(rc))
return rc;
if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc);
should_unlock = true;
}
@ -556,10 +556,10 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
__cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!arg))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*arg = env->flags & ENV_USABLE_FLAGS;
return MDBX_SUCCESS;
@ -568,7 +568,7 @@ __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
__cold int mdbx_env_set_userctx(MDBX_env *env, void *ctx) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
env->userctx = ctx;
return MDBX_SUCCESS;
@ -581,21 +581,21 @@ __cold void *mdbx_env_get_userctx(const MDBX_env *env) {
__cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
#if MDBX_DEBUG
env->assert_func = func;
return MDBX_SUCCESS;
#else
(void)func;
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
#endif
}
__cold int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr) {
int rc = check_env(env, false);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
env->hsr_callback = hsr;
return MDBX_SUCCESS;
@ -610,10 +610,10 @@ __cold MDBX_hsr_func *mdbx_env_get_hsr(const MDBX_env *env) {
__cold int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **arg) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!arg))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*arg = env->pathname.specified;
return MDBX_SUCCESS;
@ -623,10 +623,10 @@ __cold int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **arg) {
__cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!arg))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
#if defined(_WIN32) || defined(_WIN64)
if (!env->pathname_char) {
@ -643,17 +643,17 @@ __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
rc = mb_len ? MDBX_SUCCESS : (int)GetLastError();
}
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
char *const mb_pathname = osal_malloc(mb_len);
if (!mb_pathname)
return MDBX_ENOMEM;
return LOG_IFERR(MDBX_ENOMEM);
if (mb_len != (size_t)WideCharToMultiByte(
CP_THREAD_ACP, flags, env->pathname.specified, -1,
mb_pathname, (int)mb_len, nullptr, nullptr)) {
rc = (int)GetLastError();
osal_free(mb_pathname);
return rc;
return LOG_IFERR(rc);
}
if (env->pathname_char ||
InterlockedCompareExchangePointer((PVOID volatile *)&env->pathname_char,

View File

@ -844,26 +844,26 @@ __cold int mdbx_txn_copy2fd(MDBX_txn *txn, mdbx_filehandle_t fd,
rc = copy2fd(txn, fd, flags);
if (flags & MDBX_CP_DISPOSE_TXN)
mdbx_txn_abort(txn);
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
MDBX_copy_flags_t flags) {
if (unlikely(flags & (MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
MDBX_txn *txn = nullptr;
rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = copy2fd(txn, fd, flags | MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN);
mdbx_txn_abort(txn);
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest_path,
@ -875,7 +875,7 @@ __cold int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest_path,
rc = mdbx_txn_copy2pathnameW(txn, dest_pathW, flags);
osal_free(dest_pathW);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest_path,
@ -886,7 +886,7 @@ __cold int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest_path,
rc = copy2pathname(txn, dest_path, flags);
if (flags & MDBX_CP_DISPOSE_TXN)
mdbx_txn_abort(txn);
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
@ -898,26 +898,26 @@ __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
rc = mdbx_env_copyW(env, dest_pathW, flags);
osal_free(dest_pathW);
}
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest_path,
MDBX_copy_flags_t flags) {
#endif /* Windows */
if (unlikely(flags & (MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
MDBX_txn *txn = nullptr;
rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = copy2pathname(txn, dest_path,
flags | MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN);
mdbx_txn_abort(txn);
return rc;
return LOG_IFERR(rc);
}

View File

@ -745,35 +745,35 @@ static defer_free_item_t *dbi_close_locked(MDBX_env *env, MDBX_dbi dbi) {
int mdbx_dbi_open(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags,
MDBX_dbi *dbi) {
return dbi_open_cstr(txn, name, flags, dbi, nullptr, nullptr);
return LOG_IFERR(dbi_open_cstr(txn, name, flags, dbi, nullptr, nullptr));
}
int mdbx_dbi_open2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags,
MDBX_dbi *dbi) {
return dbi_open(txn, name, flags, dbi, nullptr, nullptr);
return LOG_IFERR(dbi_open(txn, name, flags, dbi, nullptr, nullptr));
}
int mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags,
MDBX_dbi *dbi, MDBX_cmp_func *keycmp,
MDBX_cmp_func *datacmp) {
return dbi_open_cstr(txn, name, flags, dbi, keycmp, datacmp);
return LOG_IFERR(dbi_open_cstr(txn, name, flags, dbi, keycmp, datacmp));
}
int mdbx_dbi_open_ex2(MDBX_txn *txn, const MDBX_val *name,
MDBX_db_flags_t flags, MDBX_dbi *dbi,
MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp) {
return dbi_open(txn, name, flags, dbi, keycmp, datacmp);
return LOG_IFERR(dbi_open(txn, name, flags, dbi, keycmp, datacmp));
}
__cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (txn->dbs[dbi].height) {
cx.outer.next = txn->cursors[dbi];
@ -782,7 +782,7 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
dbi == MAIN_DBI || (cx.outer.tree->flags & MDBX_DUPSORT));
txn->cursors[dbi] = cx.outer.next;
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
/* Invalidate the dropped DB's cursors */
@ -820,12 +820,12 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
txn->dbi_state[dbi] = DBI_LINDO | DBI_OLDEN;
rc = osal_fastmutex_acquire(&env->dbi_lock);
if (likely(rc == MDBX_SUCCESS))
return defer_and_release(env, dbi_close_locked(env, dbi));
return LOG_IFERR(defer_and_release(env, dbi_close_locked(env, dbi)));
}
}
}
txn->flags |= MDBX_TXN_ERROR;
return rc;
return LOG_IFERR(rc);
}
__cold int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name_cstr) {
@ -838,22 +838,22 @@ __cold int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name_cstr) {
thunk.iov_base = (void *)name_cstr;
name = &thunk;
}
return mdbx_dbi_rename2(txn, dbi, name);
return LOG_IFERR(mdbx_dbi_rename2(txn, dbi, name));
}
int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(dbi < CORE_DBS))
return (dbi == MAIN_DBI) ? MDBX_SUCCESS : MDBX_BAD_DBI;
return (dbi == MAIN_DBI) ? MDBX_SUCCESS : LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(dbi >= env->max_dbi))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
if (unlikely(dbi < CORE_DBS || dbi >= env->max_dbi))
return MDBX_BAD_DBI;
return LOG_IFERR(MDBX_BAD_DBI);
rc = osal_fastmutex_acquire(&env->dbi_lock);
if (likely(rc == MDBX_SUCCESS && dbi < env->n_dbi)) {
@ -886,7 +886,7 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
(DBI_LINDO | DBI_DIRTY | DBI_CREAT)) > DBI_LINDO) {
bailout_dirty_dbi:
osal_fastmutex_release(&env->dbi_lock);
return MDBX_DANGLING_DBI;
return LOG_IFERR(MDBX_DANGLING_DBI);
}
osal_memory_barrier();
if (unlikely(hazard != env->txn))
@ -903,21 +903,21 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
}
rc = defer_and_release(env, dbi_close_locked(env, dbi));
}
return rc;
return LOG_IFERR(rc);
}
int mdbx_dbi_flags_ex(const MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags,
unsigned *state) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR - MDBX_TXN_PARKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!flags || !state))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
*flags = txn->dbs[dbi].flags & DB_PERSISTENT_FLAGS;
*state =
@ -930,19 +930,19 @@ __cold int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi,
const MDBX_val *new_name) {
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(new_name == MDBX_CHK_MAIN ||
new_name->iov_base == MDBX_CHK_MAIN || new_name == MDBX_CHK_GC ||
new_name->iov_base == MDBX_CHK_GC || new_name == MDBX_CHK_META ||
new_name->iov_base == MDBX_CHK_META))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(dbi < CORE_DBS))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = osal_fastmutex_acquire(&txn->env->dbi_lock);
if (likely(rc == MDBX_SUCCESS)) {
@ -952,7 +952,7 @@ __cold int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi,
defer_and_release(txn->env, pair.defer);
rc = pair.err;
}
return rc;
return LOG_IFERR(rc);
}
static void stat_get(const tree_t *db, MDBX_stat *st, size_t bytes) {
@ -970,26 +970,26 @@ __cold int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest,
size_t bytes) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!dest))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid);
if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid)
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(txn->flags & MDBX_TXN_BLOCKED))
return MDBX_BAD_TXN;
return LOG_IFERR(MDBX_BAD_TXN);
if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) {
rc = tbl_fetch((MDBX_txn *)txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
dest->ms_psize = txn->env->ps;
@ -1024,16 +1024,16 @@ __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi,
__cold int mdbx_enumerate_tables(const MDBX_txn *txn,
MDBX_table_enum_func *func, void *ctx) {
if (unlikely(!func))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, MAIN_DBI);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cx.outer.next = txn->cursors[MAIN_DBI];
txn->cursors[MAIN_DBI] = &cx.outer;
@ -1076,5 +1076,5 @@ __cold int mdbx_enumerate_tables(const MDBX_txn *txn,
bailout:
txn->cursors[MAIN_DBI] = cx.outer.next;
return rc;
return LOG_IFERR(rc);
}

View File

@ -105,7 +105,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
uint64_t value) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
const bool lock_needed =
((env->flags & ENV_ACTIVE) && env->basal_txn && !env_txn0_owned(env));
@ -115,11 +115,11 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = MAX_WRITE;
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(!(env->flags & ENV_ACTIVE)))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
if (unlikely(value > SIZE_MAX - 65536))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
value = bytes2pgno(env, (size_t)value + env->ps - 1);
if ((uint32_t)value !=
atomic_load32(&env->lck->autosync_threshold, mo_AcquireRelease) &&
@ -138,11 +138,11 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 2780315 /* 42.42424 секунды */;
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (unlikely(!(env->flags & ENV_ACTIVE)))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
if (unlikely(value > UINT32_MAX))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
value = osal_16dot16_to_monotime((uint32_t)value);
if (value != atomic_load64(&env->lck->autosync_period, mo_AcquireRelease) &&
atomic_store64(&env->lck->autosync_period, value, mo_Relaxed)
@ -159,9 +159,9 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 42;
if (unlikely(value > MDBX_MAX_DBI))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->dxb_mmap.base))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
env->max_dbi = (unsigned)value + CORE_DBS;
break;
@ -169,9 +169,9 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = MDBX_READERS_LIMIT;
if (unlikely(value < 1 || value > MDBX_READERS_LIMIT))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->dxb_mmap.base))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
env->max_readers = (unsigned)value;
break;
@ -179,12 +179,12 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = INT_MAX;
if (unlikely(value > INT_MAX))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (env->options.dp_reserve_limit != (unsigned)value) {
if (lock_needed) {
err = lck_txn_lock(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
should_unlock = true;
}
env->options.dp_reserve_limit = (unsigned)value;
@ -206,7 +206,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
env->options.flags.non_auto.rp_augment_limit = 0;
env->options.rp_augment_limit = default_rp_augment_limit(env);
} else if (unlikely(value > PAGELIST_LIMIT))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
else {
env->options.flags.non_auto.rp_augment_limit = 1;
env->options.rp_augment_limit = (unsigned)value;
@ -217,13 +217,13 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 0;
if (unlikely(value > UINT32_MAX))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
value = osal_16dot16_to_monotime((uint32_t)value);
if (value != env->options.gc_time_limit) {
if (env->txn && lock_needed)
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
env->options.gc_time_limit = value;
if (!env->options.flags.non_auto.rp_augment_limit)
env->options.rp_augment_limit = default_rp_augment_limit(env);
@ -235,13 +235,13 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = PAGELIST_LIMIT;
if (unlikely(value > PAGELIST_LIMIT || value < CURSOR_STACK_SIZE * 4))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(env->flags & MDBX_RDONLY))
return MDBX_EACCESS;
return LOG_IFERR(MDBX_EACCESS);
if (lock_needed) {
err = lck_txn_lock(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
should_unlock = true;
}
if (env->txn)
@ -269,21 +269,21 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 8;
if (unlikely(value > 255))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
env->options.spill_max_denominator = (uint8_t)value;
break;
case MDBX_opt_spill_min_denominator:
if (value == /* default */ UINT64_MAX)
value = 8;
if (unlikely(value > 255))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
env->options.spill_min_denominator = (uint8_t)value;
break;
case MDBX_opt_spill_parent4child_denominator:
if (value == /* default */ UINT64_MAX)
value = 0;
if (unlikely(value > 255))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
env->options.spill_parent4child_denominator = (uint8_t)value;
break;
@ -291,7 +291,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 64;
if (unlikely(value > 255))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
env->options.dp_loose_limit = (uint8_t)value;
break;
@ -299,7 +299,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
if (value == /* default */ UINT64_MAX)
value = 65536 / 4 /* 25% */;
if (unlikely(value < 8192 || value > 32768))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
env->options.merge_threshold_16dot16_percent = (unsigned)value;
recalculate_merge_thresholds(env);
break;
@ -392,33 +392,33 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
break;
default:
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
}
if (should_unlock)
lck_txn_unlock(env);
return err;
return LOG_IFERR(err);
}
__cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option,
uint64_t *pvalue) {
int err = check_env(env, false);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
if (unlikely(!pvalue))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
switch (option) {
case MDBX_opt_sync_bytes:
if (unlikely(!(env->flags & ENV_ACTIVE)))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
*pvalue = pgno2bytes(
env, atomic_load32(&env->lck->autosync_threshold, mo_Relaxed));
break;
case MDBX_opt_sync_period:
if (unlikely(!(env->flags & ENV_ACTIVE)))
return MDBX_EPERM;
return LOG_IFERR(MDBX_EPERM);
*pvalue = osal_monotime_to_16dot16(
atomic_load64(&env->lck->autosync_period, mo_Relaxed));
break;
@ -501,7 +501,7 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option,
break;
default:
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
}
return MDBX_SUCCESS;

View File

@ -59,6 +59,16 @@ __cold void debug_log(int level, const char *function, int line,
va_end(args);
}
__cold int log_error(const int err, const char *func, unsigned line) {
assert(err != MDBX_SUCCESS);
if (unlikely(globals.loglevel >= MDBX_LOG_DEBUG)) {
char buf[256];
debug_log(MDBX_LOG_ERROR, func, line, "error %d (%s)\n", err,
mdbx_strerror_r(err, buf, sizeof(buf)));
}
return err;
}
/* Dump a val in ascii or hexadecimal. */
__cold const char *mdbx_dump_val(const MDBX_val *val, char *const buf,
const size_t bufsize) {

View File

@ -158,3 +158,11 @@ MDBX_INTERNAL const char *pagetype_caption(const uint8_t type,
#define DKEY_DEBUG(x) ("-")
#define DVAL_DEBUG(x) ("-")
#endif
MDBX_INTERNAL int log_error(const int err, const char *func, unsigned line);
static inline int log_if_error(int err, const char *func, unsigned line) {
return likely(err == MDBX_SUCCESS) ? err : log_error(err, func, line);
}
#define LOG_IFERR(err) log_if_error((err), __func__, __LINE__)

View File

@ -10,7 +10,7 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) {
intptr_t pagesize, total_ram_pages;
int err = mdbx_get_sysraminfo(&pagesize, &total_ram_pages, nullptr);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
const int log2page = log2n_powerof2(pagesize);
const intptr_t volume_pages = (volume + pagesize - 1) >> log2page;
@ -24,7 +24,7 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) {
intptr_t avail_ram_pages;
err = mdbx_get_sysraminfo(nullptr, nullptr, &avail_ram_pages);
if (unlikely(err != MDBX_SUCCESS))
return err;
return LOG_IFERR(err);
return (volume_pages + redundancy_pages >= avail_ram_pages)
? MDBX_RESULT_FALSE
@ -35,16 +35,16 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
uint64_t increment) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = dbi_check(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) {
rc = tbl_fetch(txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
tree_t *dbs = &txn->dbs[dbi];
@ -95,10 +95,10 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
cursor_couple_t cx;
rc = cursor_init(&cx.outer, txn, MAIN_DBI);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
rc = tree_search(&cx.outer, nullptr, Z_MODIFY | Z_ROOTONLY);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
}
dbs->sequence = new;

View File

@ -536,14 +536,14 @@ __cold txnid_t mvcc_kick_laggards(MDBX_env *env, const txnid_t straggler) {
__cold int mdbx_thread_register(const MDBX_env *env) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!env->lck_mmap.lck))
return (env->flags & MDBX_EXCLUSIVE) ? MDBX_EINVAL : MDBX_EPERM;
return LOG_IFERR((env->flags & MDBX_EXCLUSIVE) ? MDBX_EINVAL : MDBX_EPERM);
if (unlikely((env->flags & ENV_TXKEY) == 0)) {
eASSERT(env, env->flags & MDBX_NOSTICKYTHREADS);
return MDBX_EINVAL /* MDBX_NOSTICKYTHREADS mode */;
return LOG_IFERR(MDBX_EINVAL) /* MDBX_NOSTICKYTHREADS mode */;
}
eASSERT(env, (env->flags & (MDBX_NOSTICKYTHREADS | ENV_TXKEY)) == ENV_TXKEY);
@ -552,17 +552,17 @@ __cold int mdbx_thread_register(const MDBX_env *env) {
eASSERT(env, r->pid.weak == env->pid);
eASSERT(env, r->tid.weak == osal_thread_self());
if (unlikely(r->pid.weak != env->pid))
return MDBX_BAD_RSLOT;
return LOG_IFERR(MDBX_BAD_RSLOT);
return MDBX_RESULT_TRUE /* already registered */;
}
return mvcc_bind_slot((MDBX_env *)env).err;
return LOG_IFERR(mvcc_bind_slot((MDBX_env *)env).err);
}
__cold int mdbx_thread_unregister(const MDBX_env *env) {
int rc = check_env(env, true);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!env->lck_mmap.lck))
return MDBX_RESULT_TRUE;
@ -580,11 +580,11 @@ __cold int mdbx_thread_unregister(const MDBX_env *env) {
eASSERT(env, r->pid.weak == env->pid);
eASSERT(env, r->tid.weak == osal_thread_self());
if (unlikely(r->pid.weak != env->pid || r->tid.weak != osal_thread_self()))
return MDBX_BAD_RSLOT;
return LOG_IFERR(MDBX_BAD_RSLOT);
eASSERT(env, r->txnid.weak >= SAFE64_INVALID_THRESHOLD);
if (unlikely(r->txnid.weak < SAFE64_INVALID_THRESHOLD))
return MDBX_BUSY /* transaction is still active */;
return LOG_IFERR(MDBX_BUSY) /* transaction is still active */;
atomic_store32(&r->pid, 0, mo_Relaxed);
atomic_store32(&env->lck->rdt_refresh_flag, true, mo_AcquireRelease);

View File

@ -3405,7 +3405,7 @@ __cold static bin128_t osal_bootid(void) {
__cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
intptr_t *avail_pages) {
if (!page_size && !total_pages && !avail_pages)
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (total_pages)
*total_pages = -1;
if (avail_pages)
@ -3415,7 +3415,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
if (page_size)
*page_size = pagesize;
if (unlikely(pagesize < MDBX_MIN_PAGESIZE || !is_powerof2(pagesize)))
return MDBX_INCOMPATIBLE;
return LOG_IFERR(MDBX_INCOMPATIBLE);
MDBX_MAYBE_UNUSED const int log2page = log2n_powerof2(pagesize);
assert(pagesize == (INT64_C(1) << log2page));
@ -3426,7 +3426,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
memset(&info, 0, sizeof(info));
info.dwLength = sizeof(info);
if (!GlobalMemoryStatusEx(&info))
return (int)GetLastError();
return LOG_IFERR((int)GetLastError());
#endif
if (total_pages) {
@ -3435,11 +3435,11 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
#elif defined(_SC_PHYS_PAGES)
const intptr_t total_ram_pages = sysconf(_SC_PHYS_PAGES);
if (total_ram_pages == -1)
return errno;
return LOG_IFERR(errno);
#elif defined(_SC_AIX_REALMEM)
const intptr_t total_ram_Kb = sysconf(_SC_AIX_REALMEM);
if (total_ram_Kb == -1)
return errno;
return LOG_IFERR(errno);
const intptr_t total_ram_pages = (total_ram_Kb << 10) >> log2page;
#elif defined(HW_USERMEM) || defined(HW_PHYSMEM64) || defined(HW_MEMSIZE) || \
defined(HW_PHYSMEM)
@ -3461,16 +3461,16 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
#endif
mib,
ARRAY_LENGTH(mib), &ram, &len, nullptr, 0) != 0)
return errno;
return LOG_IFERR(errno);
if (len != sizeof(ram))
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
const intptr_t total_ram_pages = (intptr_t)(ram >> log2page);
#else
#error "FIXME: Get User-accessible or physical RAM"
#endif
*total_pages = total_ram_pages;
if (total_ram_pages < 1)
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
}
if (avail_pages) {
@ -3479,7 +3479,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
#elif defined(_SC_AVPHYS_PAGES)
const intptr_t avail_ram_pages = sysconf(_SC_AVPHYS_PAGES);
if (avail_ram_pages == -1)
return errno;
return LOG_IFERR(errno);
#elif defined(__MACH__)
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
@ -3488,7 +3488,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
(host_info_t)&vmstat, &count);
mach_port_deallocate(mach_task_self(), mport);
if (unlikely(kerr != KERN_SUCCESS))
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
const intptr_t avail_ram_pages = vmstat.free_count;
#elif defined(VM_TOTAL) || defined(VM_METER)
struct vmtotal info;
@ -3506,16 +3506,16 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
#endif
mib,
ARRAY_LENGTH(mib), &info, &len, nullptr, 0) != 0)
return errno;
return LOG_IFERR(errno);
if (len != sizeof(info))
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
const intptr_t avail_ram_pages = info.t_free;
#else
#error "FIXME: Get Available RAM"
#endif
*avail_pages = avail_ram_pages;
if (avail_ram_pages < 1)
return MDBX_ENOSYS;
return LOG_IFERR(MDBX_ENOSYS);
}
return MDBX_SUCCESS;

View File

@ -154,13 +154,13 @@ __hot int mdbx_estimate_distance(const MDBX_cursor *first,
ptrdiff_t *distance_items) {
if (unlikely(first == nullptr || last == nullptr ||
distance_items == nullptr))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
*distance_items = 0;
diff_t dr;
int rc = cursor_diff(last, first, &dr);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cASSERT(first, dr.diff || inner_pointed(first) == inner_pointed(last));
if (unlikely(dr.diff == 0) && inner_pointed(first)) {
@ -168,7 +168,7 @@ __hot int mdbx_estimate_distance(const MDBX_cursor *first,
last = &last->subcur->cursor;
rc = cursor_diff(first, last, &dr);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
}
if (likely(dr.diff != 0))
@ -182,23 +182,24 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
ptrdiff_t *distance_items) {
if (unlikely(cursor == nullptr || distance_items == nullptr ||
move_op == MDBX_GET_CURRENT || move_op == MDBX_GET_MULTIPLE))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(cursor->signature != cur_signature_live))
return (cursor->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
: MDBX_EBADSIGN;
return LOG_IFERR((cursor->signature == cur_signature_ready4dispose)
? MDBX_EINVAL
: MDBX_EBADSIGN);
int rc = check_txn(cursor->txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!is_pointed(cursor)))
return MDBX_ENODATA;
return LOG_IFERR(MDBX_ENODATA);
cursor_couple_t next;
rc = cursor_init(&next.outer, cursor->txn, cursor_dbi(cursor));
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
cursor_cpstk(cursor, &next.outer);
if (cursor->tree->flags & MDBX_DUPSORT) {
@ -211,7 +212,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
const unsigned mask =
1 << MDBX_GET_BOTH | 1 << MDBX_GET_BOTH_RANGE | 1 << MDBX_SET_KEY;
if (unlikely(mask & (1 << move_op)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
stub_data.iov_base = nullptr;
stub_data.iov_len = 0;
data = &stub_data;
@ -223,7 +224,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
1 << MDBX_SET_KEY | 1 << MDBX_SET |
1 << MDBX_SET_RANGE;
if (unlikely(mask & (1 << move_op)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
stub_key.iov_base = nullptr;
stub_key.iov_len = 0;
key = &stub_key;
@ -233,7 +234,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
rc = cursor_ops(&next.outer, key, data, move_op);
if (unlikely(rc != MDBX_SUCCESS &&
(rc != MDBX_NOTFOUND || !is_pointed(&next.outer))))
return rc;
return LOG_IFERR(rc);
if (move_op == MDBX_LAST) {
next.outer.flags |= z_eof_hard;
@ -249,26 +250,26 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
ptrdiff_t *size_items) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(!size_items))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(begin_data &&
(begin_key == nullptr || begin_key == MDBX_EPSILON)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(end_data && (end_key == nullptr || end_key == MDBX_EPSILON)))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
if (unlikely(begin_key == MDBX_EPSILON && end_key == MDBX_EPSILON))
return MDBX_EINVAL;
return LOG_IFERR(MDBX_EINVAL);
cursor_couple_t begin;
/* LY: first, initialize cursor to refresh a DB in case it have DB_STALE */
rc = cursor_init(&begin.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (unlikely(begin.outer.tree->items == 0)) {
*size_items = 0;
@ -284,18 +285,20 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
rc = outer_first(&begin.outer, nullptr, nullptr);
if (unlikely(end_key == MDBX_EPSILON)) {
/* LY: FIRST..+epsilon case */
return (rc == MDBX_SUCCESS)
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
: rc;
return LOG_IFERR(
(rc == MDBX_SUCCESS)
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
: rc);
}
} else {
if (unlikely(begin_key == MDBX_EPSILON)) {
if (end_key == nullptr) {
/* LY: -epsilon..LAST case */
rc = outer_last(&begin.outer, nullptr, nullptr);
return (rc == MDBX_SUCCESS)
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
: rc;
return LOG_IFERR(
(rc == MDBX_SUCCESS)
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
: rc);
}
/* LY: -epsilon..value case */
assert(end_key != MDBX_EPSILON);
@ -313,7 +316,7 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
.err;
if (unlikely(rc != MDBX_SUCCESS)) {
*size_items = 0;
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
return LOG_IFERR((rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc);
}
*size_items = 1;
if (inner_pointed(&begin.outer))
@ -329,21 +332,21 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
MDBX_val proxy_data = {nullptr, 0};
if (begin_data)
proxy_data = *begin_data;
rc = cursor_seek(&begin.outer, &proxy_key, &proxy_data,
MDBX_SET_LOWERBOUND)
.err;
rc = LOG_IFERR(cursor_seek(&begin.outer, &proxy_key, &proxy_data,
MDBX_SET_LOWERBOUND)
.err);
}
}
if (unlikely(rc != MDBX_SUCCESS)) {
if (rc != MDBX_NOTFOUND || !is_pointed(&begin.outer))
return rc;
return LOG_IFERR(rc);
}
cursor_couple_t end;
rc = cursor_init(&end.outer, txn, dbi);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
if (!end_key) {
rc = outer_last(&end.outer, nullptr, nullptr);
end.outer.flags |= z_eof_hard;
@ -358,12 +361,12 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
}
if (unlikely(rc != MDBX_SUCCESS)) {
if (rc != MDBX_NOTFOUND || !is_pointed(&end.outer))
return rc;
return LOG_IFERR(rc);
}
rc = mdbx_estimate_distance(&begin.outer, &end.outer, size_items);
if (unlikely(rc != MDBX_SUCCESS))
return rc;
return LOG_IFERR(rc);
assert(*size_items >= -(ptrdiff_t)begin.outer.tree->items &&
*size_items <= (ptrdiff_t)begin.outer.tree->items);