From 444eb4dd7956bea30be49de795eb3043596ec95b Mon Sep 17 00:00:00 2001 From: selsta Date: Wed, 9 Sep 2026 22:21:10 +0200 Subject: [PATCH] lmdb: make transaction admission reentrant (cherry picked from commit 6ee665b2c228dde4bb576f0ed7edb8d1a1702673) --- src/blockchain_db/lmdb/db_lmdb.cpp | 17 +++++++++++------ src/blockchain_db/lmdb/db_lmdb.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 9a0aa8691..54bc085ab 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -356,6 +356,7 @@ typedef struct outtx { } outtx; std::atomic mdb_txn_safe::num_active_txns{0}; +thread_local uint64_t mdb_txn_safe::num_active_txns_per_thread = 0; std::atomic_flag mdb_txn_safe::creation_gate = ATOMIC_FLAG_INIT; mdb_threadinfo::~mdb_threadinfo() @@ -373,9 +374,12 @@ mdb_txn_safe::mdb_txn_safe(const bool check) : m_txn(NULL), m_tinfo(NULL), m_che { if (check) { - while (creation_gate.test_and_set()); - num_active_txns++; - creation_gate.clear(); + const bool nested = num_active_txns_per_thread != 0; + if (!nested) + while (creation_gate.test_and_set()); + increment_txns(1); + if (!nested) + creation_gate.clear(); } } @@ -406,12 +410,12 @@ mdb_txn_safe::~mdb_txn_safe() } mdb_txn_abort(m_txn); } - num_active_txns--; + increment_txns(-1); } void mdb_txn_safe::uncheck() { - num_active_txns--; + increment_txns(-1); m_check = false; } @@ -466,7 +470,8 @@ void mdb_txn_safe::allow_new_txns() void mdb_txn_safe::increment_txns(int i) { - num_active_txns += i; + num_active_txns_per_thread += i; + num_active_txns += i; } #define TXN_PREFIX(flags); \ diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index bdae44948..7db237bc8 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -161,6 +161,7 @@ struct mdb_txn_safe bool m_batch_txn = false; bool m_check; static std::atomic num_active_txns; + static thread_local uint64_t num_active_txns_per_thread; // could use a mutex here, but this should be sufficient. static std::atomic_flag creation_gate;