mdbx: проверка владельца потока владеющего транзакцией только при MDBX_TXN_CHECKOWNER=ON (backport).

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-03-04 10:44:42 +03:00
parent bc2f1c59cb
commit 0604accecf
4 changed files with 9 additions and 2 deletions

View File

@ -648,7 +648,7 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
#endif /* Windows */ #endif /* Windows */
} }
if (env->basal_txn && env->basal_txn->owner == osal_thread_self()) if (env->basal_txn && (MDBX_TXN_CHECKOWNER ? env->basal_txn->owner == osal_thread_self() : !!env->basal_txn->owner))
lck_txn_unlock(env); lck_txn_unlock(env);
eASSERT(env, env->signature.weak == 0); eASSERT(env, env->signature.weak == 0);

View File

@ -117,7 +117,6 @@ __cold int mdbx_thread_unregister(const MDBX_env *env) {
return MDBX_RESULT_TRUE /* not registered */; return MDBX_RESULT_TRUE /* not registered */;
eASSERT(env, r->pid.weak == env->pid); 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())) if (unlikely(r->pid.weak != env->pid || r->tid.weak != osal_thread_self()))
return LOG_IFERR(MDBX_BAD_RSLOT); return LOG_IFERR(MDBX_BAD_RSLOT);
@ -154,8 +153,10 @@ int mdbx_txn_unlock(MDBX_env *env) {
if (unlikely(env->flags & MDBX_RDONLY)) if (unlikely(env->flags & MDBX_RDONLY))
return LOG_IFERR(MDBX_EACCESS); return LOG_IFERR(MDBX_EACCESS);
#if MDBX_TXN_CHECKOWNER
if (unlikely(env->basal_txn->owner != osal_thread_self())) if (unlikely(env->basal_txn->owner != osal_thread_self()))
return LOG_IFERR(MDBX_THREAD_MISMATCH); return LOG_IFERR(MDBX_THREAD_MISMATCH);
#endif /* MDBX_TXN_CHECKOWNER */
if (unlikely((env->basal_txn->flags & MDBX_TXN_FINISHED) == 0)) if (unlikely((env->basal_txn->flags & MDBX_TXN_FINISHED) == 0))
return LOG_IFERR(MDBX_BUSY); return LOG_IFERR(MDBX_BUSY);

View File

@ -101,11 +101,13 @@ int mdbx_txn_abort(MDBX_txn *txn) {
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return LOG_IFERR(rc); return LOG_IFERR(rc);
#if MDBX_TXN_CHECKOWNER
if ((txn->flags & (MDBX_TXN_RDONLY | MDBX_NOSTICKYTHREADS)) == MDBX_NOSTICKYTHREADS && if ((txn->flags & (MDBX_TXN_RDONLY | MDBX_NOSTICKYTHREADS)) == MDBX_NOSTICKYTHREADS &&
unlikely(txn->owner != osal_thread_self())) { unlikely(txn->owner != osal_thread_self())) {
mdbx_txn_break(txn); mdbx_txn_break(txn);
return LOG_IFERR(MDBX_THREAD_MISMATCH); return LOG_IFERR(MDBX_THREAD_MISMATCH);
} }
#endif /* MDBX_TXN_CHECKOWNER */
return LOG_IFERR(txn_abort(txn)); return LOG_IFERR(txn_abort(txn));
} }
@ -420,11 +422,13 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
goto done; goto done;
} }
#if MDBX_TXN_CHECKOWNER
if (!txn->parent && (txn->flags & MDBX_NOSTICKYTHREADS) && unlikely(txn->owner != osal_thread_self())) { if (!txn->parent && (txn->flags & MDBX_NOSTICKYTHREADS) && unlikely(txn->owner != osal_thread_self())) {
txn->flags |= MDBX_TXN_ERROR; txn->flags |= MDBX_TXN_ERROR;
rc = MDBX_THREAD_MISMATCH; rc = MDBX_THREAD_MISMATCH;
return LOG_IFERR(rc); return LOG_IFERR(rc);
} }
#endif /* MDBX_TXN_CHECKOWNER */
if (unlikely(txn->flags & MDBX_TXN_ERROR)) { if (unlikely(txn->flags & MDBX_TXN_ERROR)) {
rc = MDBX_RESULT_TRUE; rc = MDBX_RESULT_TRUE;

View File

@ -131,6 +131,7 @@ int main(int argc, const char *argv[]) {
std::thread t([&]() { std::thread t([&]() {
s.wait(); s.wait();
#if MDBX_TXN_CHECKOWNER
err = mdbx_txn_reset(c_txn); err = mdbx_txn_reset(c_txn);
assert(err == MDBX_THREAD_MISMATCH); assert(err == MDBX_THREAD_MISMATCH);
ok = ok && err == MDBX_THREAD_MISMATCH; ok = ok && err == MDBX_THREAD_MISMATCH;
@ -143,6 +144,7 @@ int main(int argc, const char *argv[]) {
err = mdbx_txn_abort(c_txn); err = mdbx_txn_abort(c_txn);
assert(err == MDBX_THREAD_MISMATCH); assert(err == MDBX_THREAD_MISMATCH);
ok = ok && err == MDBX_THREAD_MISMATCH; ok = ok && err == MDBX_THREAD_MISMATCH;
#endif /* MDBX_TXN_CHECKOWNER */
err = mdbx_txn_begin(env, txn, MDBX_TXN_READWRITE, &c_txn); err = mdbx_txn_begin(env, txn, MDBX_TXN_READWRITE, &c_txn);
assert(err == MDBX_BAD_TXN); assert(err == MDBX_BAD_TXN);
ok = ok && err == MDBX_BAD_TXN; ok = ok && err == MDBX_BAD_TXN;