mdbx: освобождение памяти сброшенных/прерванных читающих транзакций передаваемых в mdbx_txn_commit().

Исторически в API была слабость/неоднозначность в жизненном цикле читающих транзакций:

 - В простейших сценариях читающие транзакции запускались посредством
   mdbx_txn_begin() и завершались посредством mdbx_txn_abort(), либо mdbx_txn_commit();

 - Для экономии накладных расходов были предусмотрены функции
   mdbx_txn_reset() и mdbx_txn_renew(), которые сбрасывали/прерывали
   читающую транзакцию без её освобождения/разрушения и затем перезапускали её.
   При этом транзакции сброшенные посредством mdbx_txn_reset() должны были
   быть либо перезапущены, либо освобождены посредством mdbx_txn_abort();

 - Заминка возникала при вызове mdbx_txn_commit() для читающих
   транзакций сброшенных/прерванных посредством mdbx_txn_reset().
   В таких ситуациях возвращалась ошибка MDBX_BAD_TXN, а транзакция
   не освобождалась.

Такое поведение вносило лишнюю асимметрию в API и способствовало
появлению ошибок утечки ресурсов, но поддерживалось для совместимости.

Этот коммит изменяет историческое поведение с нарушением совместимости,
но делает API более регулярным и уменьшает вероятность ошибок утечки
ресурсов.

Теперь mdbx_txn_commit() освобождает/разрушает читающие транзакции
сброшенные/прерванные посредством mdbx_txn_reset() возвращая при этом
MDBX_RESULT_TRUE вместо MDBX_SUCCESS, по аналогии обработки фиксации
аварийных пишущих транзакций.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-11-17 17:42:00 +03:00
parent efaa46d7cd
commit ddea36c54a

View File

@ -460,20 +460,22 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
int rc = check_txn(txn, MDBX_TXN_FINISHED);
if (unlikely(rc != MDBX_SUCCESS)) {
if (rc == MDBX_BAD_TXN && (txn->flags & MDBX_TXN_RDONLY)) {
rc = MDBX_RESULT_TRUE;
goto fail;
}
bailout:
if (latency)
memset(latency, 0, sizeof(*latency));
return rc;
}
MDBX_env *const env = txn->env;
#if MDBX_ENV_CHECKPID
if (unlikely(env->pid != osal_getpid())) {
if (MDBX_ENV_CHECKPID && unlikely(env->pid != osal_getpid())) {
env->flags |= ENV_FATAL_ERROR;
if (latency)
memset(latency, 0, sizeof(*latency));
return MDBX_PANIC;
rc = MDBX_PANIC;
goto bailout;
}
#endif /* MDBX_ENV_CHECKPID */
if (unlikely(txn->flags & MDBX_TXN_ERROR)) {
rc = MDBX_RESULT_TRUE;