mirror of
https://github.com/isar/libmdbx.git
synced 2025-04-02 15:22:58 +08:00
mdbx: переработка mdbx_txn_release_all_cursors_ex()
(backport).
This commit is contained in:
parent
682233ba28
commit
5fd319bbc2
26
mdbx.h
26
mdbx.h
@ -5261,15 +5261,12 @@ LIBMDBX_API void mdbx_cursor_close(MDBX_cursor *cursor);
|
|||||||
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
||||||
LIBMDBX_API int mdbx_cursor_close2(MDBX_cursor *cursor);
|
LIBMDBX_API int mdbx_cursor_close2(MDBX_cursor *cursor);
|
||||||
|
|
||||||
/** \brief Unbind or closes all cursors of a given transaction.
|
/** \brief Unbind or closes all cursors of a given transaction and of all
|
||||||
|
* its parent transactions if ones are.
|
||||||
* \ingroup c_cursors
|
* \ingroup c_cursors
|
||||||
*
|
*
|
||||||
* Unbinds either closes all cursors associated (opened or renewed) with
|
* Unbinds either closes all cursors associated (opened, renewed or binded) with
|
||||||
* a given transaction in a bulk with minimal overhead.
|
* the given transaction in a bulk with minimal overhead.
|
||||||
*
|
|
||||||
* A transaction should not be nested, since in this case no way to restore
|
|
||||||
* state if this nested transaction will be aborted, nor impossible to define
|
|
||||||
* the expected behavior.
|
|
||||||
*
|
*
|
||||||
* \see mdbx_cursor_unbind()
|
* \see mdbx_cursor_unbind()
|
||||||
* \see mdbx_cursor_close()
|
* \see mdbx_cursor_close()
|
||||||
@ -5284,19 +5281,16 @@ LIBMDBX_API int mdbx_cursor_close2(MDBX_cursor *cursor);
|
|||||||
* some possible errors are:
|
* some possible errors are:
|
||||||
* \retval MDBX_THREAD_MISMATCH Given transaction is not owned
|
* \retval MDBX_THREAD_MISMATCH Given transaction is not owned
|
||||||
* by current thread.
|
* by current thread.
|
||||||
* \retval MDBX_BAD_TXN Given transaction is invalid, nested or has
|
* \retval MDBX_BAD_TXN Given transaction is invalid or has
|
||||||
* a child/nested transaction transaction. */
|
* a child/nested transaction transaction. */
|
||||||
LIBMDBX_API int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind, size_t *count);
|
LIBMDBX_API int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind, size_t *count);
|
||||||
|
|
||||||
/** \brief Unbind or closes all cursors of a given transaction.
|
/** \brief Unbind or closes all cursors of a given transaction and of all
|
||||||
|
* its parent transactions if ones are.
|
||||||
* \ingroup c_cursors
|
* \ingroup c_cursors
|
||||||
*
|
*
|
||||||
* Unbinds either closes all cursors associated (opened or renewed) with
|
* Unbinds either closes all cursors associated (opened, renewed or binded) with
|
||||||
* a given transaction in a bulk with minimal overhead.
|
* the given transaction in a bulk with minimal overhead.
|
||||||
*
|
|
||||||
* A transaction should not be nested, since in this case no way to restore
|
|
||||||
* state if this nested transaction will be aborted, nor impossible to define
|
|
||||||
* the expected behavior.
|
|
||||||
*
|
*
|
||||||
* \see mdbx_cursor_unbind()
|
* \see mdbx_cursor_unbind()
|
||||||
* \see mdbx_cursor_close()
|
* \see mdbx_cursor_close()
|
||||||
@ -5309,7 +5303,7 @@ LIBMDBX_API int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind
|
|||||||
* some possible errors are:
|
* some possible errors are:
|
||||||
* \retval MDBX_THREAD_MISMATCH Given transaction is not owned
|
* \retval MDBX_THREAD_MISMATCH Given transaction is not owned
|
||||||
* by current thread.
|
* by current thread.
|
||||||
* \retval MDBX_BAD_TXN Given transaction is invalid, nested or has
|
* \retval MDBX_BAD_TXN Given transaction is invalid or has
|
||||||
* a child/nested transaction transaction. */
|
* a child/nested transaction transaction. */
|
||||||
LIBMDBX_INLINE_API(int, mdbx_txn_release_all_cursors, (const MDBX_txn *txn, bool unbind)) {
|
LIBMDBX_INLINE_API(int, mdbx_txn_release_all_cursors, (const MDBX_txn *txn, bool unbind)) {
|
||||||
return mdbx_txn_release_all_cursors_ex(txn, unbind, NULL);
|
return mdbx_txn_release_all_cursors_ex(txn, unbind, NULL);
|
||||||
|
@ -233,28 +233,43 @@ int mdbx_txn_release_all_cursors_ex(const MDBX_txn *txn, bool unbind, size_t *co
|
|||||||
int rc = check_txn(txn, MDBX_TXN_FINISHED | MDBX_TXN_HAS_CHILD);
|
int rc = check_txn(txn, MDBX_TXN_FINISHED | MDBX_TXN_HAS_CHILD);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return LOG_IFERR(rc);
|
return LOG_IFERR(rc);
|
||||||
if (unlikely(txn->parent)) {
|
|
||||||
rc = MDBX_BAD_TXN;
|
|
||||||
ERROR("%s, err %d", "must not unbind or close cursors for a nested txn", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
TXN_FOREACH_DBI_FROM(txn, i, MAIN_DBI) {
|
do {
|
||||||
while (txn->cursors[i]) {
|
TXN_FOREACH_DBI_FROM(txn, i, MAIN_DBI) {
|
||||||
++n;
|
MDBX_cursor *mc = txn->cursors[i], *next = nullptr;
|
||||||
MDBX_cursor *mc = txn->cursors[i];
|
if (mc) {
|
||||||
ENSURE(nullptr, mc->signature == cur_signature_live && (mc->next != mc) && !mc->backup);
|
txn->cursors[i] = nullptr;
|
||||||
txn->cursors[i] = mc->next;
|
do {
|
||||||
mc->next = mc;
|
next = mc->next;
|
||||||
mc->signature = cur_signature_ready4dispose;
|
if (mc->signature == cur_signature_live) {
|
||||||
cursor_drown((cursor_couple_t *)mc);
|
mc->signature = cur_signature_wait4eot;
|
||||||
if (!unbind) {
|
cursor_drown((cursor_couple_t *)mc);
|
||||||
mc->signature = 0;
|
} else
|
||||||
osal_free(mc);
|
ENSURE(nullptr, mc->signature == cur_signature_wait4eot);
|
||||||
|
if (mc->backup) {
|
||||||
|
MDBX_cursor *bk = mc->backup;
|
||||||
|
mc->next = bk->next;
|
||||||
|
mc->backup = bk->backup;
|
||||||
|
mc->backup = nullptr;
|
||||||
|
bk->signature = 0;
|
||||||
|
bk = bk->next;
|
||||||
|
osal_free(bk);
|
||||||
|
} else {
|
||||||
|
mc->signature = cur_signature_ready4dispose;
|
||||||
|
mc->next = mc;
|
||||||
|
++n;
|
||||||
|
if (!unbind) {
|
||||||
|
mc->signature = 0;
|
||||||
|
osal_free(mc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while ((mc = next) != nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
txn = txn->parent;
|
||||||
|
} while (txn);
|
||||||
|
|
||||||
if (count)
|
if (count)
|
||||||
*count = n;
|
*count = n;
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user