mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-29 09:38:49 +08:00
mdbx: исправление утечки памяти из-за регресса в txn_end()
при добавлении парковки транзакций.
Если читающая транзакция была припаркована и затем вытеснена, то при её завершении ресурсы не освобождались.
This commit is contained in:
parent
c13efb791f
commit
92dec0bca9
@ -62,19 +62,18 @@ MDBX_INTERNAL int txn_check_badbits_parked(const MDBX_txn *txn, int bad_bits);
|
|||||||
|
|
||||||
#define TXN_END_NAMES \
|
#define TXN_END_NAMES \
|
||||||
{"committed", "empty-commit", "abort", "reset", \
|
{"committed", "empty-commit", "abort", "reset", \
|
||||||
"reset-tmp", "fail-begin", "fail-beginchild", "ousted"}
|
"fail-begin", "fail-beginchild", "ousted", nullptr}
|
||||||
enum {
|
enum {
|
||||||
/* txn_end operation number, for logging */
|
/* txn_end operation number, for logging */
|
||||||
TXN_END_COMMITTED,
|
TXN_END_COMMITTED,
|
||||||
TXN_END_PURE_COMMIT,
|
TXN_END_PURE_COMMIT,
|
||||||
TXN_END_ABORT,
|
TXN_END_ABORT,
|
||||||
TXN_END_RESET,
|
TXN_END_RESET,
|
||||||
TXN_END_RESET_TMP,
|
|
||||||
TXN_END_FAIL_BEGIN,
|
TXN_END_FAIL_BEGIN,
|
||||||
TXN_END_FAIL_BEGINCHILD,
|
TXN_END_FAIL_BEGINCHILD,
|
||||||
TXN_END_OUSTED,
|
TXN_END_OUSTED,
|
||||||
|
|
||||||
TXN_END_OPMASK = 0x0F /* mask for txn_end() operation number */,
|
TXN_END_OPMASK = 0x07 /* mask for txn_end() operation number */,
|
||||||
TXN_END_UPDATE = 0x10 /* update env state (DBIs) */,
|
TXN_END_UPDATE = 0x10 /* update env state (DBIs) */,
|
||||||
TXN_END_FREE = 0x20 /* free txn unless it is env.basal_txn */,
|
TXN_END_FREE = 0x20 /* free txn unless it is env.basal_txn */,
|
||||||
TXN_END_EOTDONE = 0x40 /* txn's cursors already closed */,
|
TXN_END_EOTDONE = 0x40 /* txn's cursors already closed */,
|
||||||
|
@ -1350,11 +1350,11 @@ int txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
MDBX_env *env = txn->env;
|
MDBX_env *env = txn->env;
|
||||||
static const char *const names[] = TXN_END_NAMES;
|
static const char *const names[] = TXN_END_NAMES;
|
||||||
|
|
||||||
DEBUG("%s txn %" PRIaTXN "%c %p on env %p, root page %" PRIaPGNO
|
DEBUG("%s txn %" PRIaTXN "%c-0x%X %p on env %p, root page %" PRIaPGNO
|
||||||
"/%" PRIaPGNO,
|
"/%" PRIaPGNO,
|
||||||
names[mode & TXN_END_OPMASK], txn->txnid,
|
names[mode & TXN_END_OPMASK], txn->txnid,
|
||||||
(txn->flags & MDBX_TXN_RDONLY) ? 'r' : 'w', (void *)txn, (void *)env,
|
(txn->flags & MDBX_TXN_RDONLY) ? 'r' : 'w', txn->flags, (void *)txn,
|
||||||
txn->dbs[MAIN_DBI].root, txn->dbs[FREE_DBI].root);
|
(void *)env, txn->dbs[MAIN_DBI].root, txn->dbs[FREE_DBI].root);
|
||||||
|
|
||||||
if (!(mode & TXN_END_EOTDONE)) /* !(already closed cursors) */
|
if (!(mode & TXN_END_EOTDONE)) /* !(already closed cursors) */
|
||||||
done_cursors(txn, false);
|
done_cursors(txn, false);
|
||||||
@ -1374,7 +1374,7 @@ int txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
} else {
|
} else {
|
||||||
if ((mode & TXN_END_OPMASK) != TXN_END_OUSTED &&
|
if ((mode & TXN_END_OPMASK) != TXN_END_OUSTED &&
|
||||||
safe64_read(&slot->tid) == MDBX_TID_TXN_OUSTED)
|
safe64_read(&slot->tid) == MDBX_TID_TXN_OUSTED)
|
||||||
mode = (mode & TXN_END_OPMASK) | TXN_END_OUSTED;
|
mode = (mode & ~TXN_END_OPMASK) | TXN_END_OUSTED;
|
||||||
do {
|
do {
|
||||||
safe64_reset(&slot->txnid, false);
|
safe64_reset(&slot->txnid, false);
|
||||||
atomic_store64(&slot->tid, txn->owner, mo_AcquireRelease);
|
atomic_store64(&slot->tid, txn->owner, mo_AcquireRelease);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user