fix(libmdbx): renew tx on timeout when dropping cursor (#10840)

This commit is contained in:
Alexey Shekhirin
2024-09-11 14:16:05 +01:00
committed by GitHub
parent 265e92685d
commit 7abf49995f
2 changed files with 26 additions and 3 deletions

View File

@ -486,8 +486,11 @@ where
K: TransactionKind,
{
fn drop(&mut self) {
// Ignore the error, because we're dropping the cursor anyway.
let _ = self.txn.txn_execute(|_| unsafe { ffi::mdbx_cursor_close(self.cursor) });
// To be able to close a cursor of a timed out transaction, we need to renew it first.
// Hence the usage of `txn_execute_renew_on_timeout` here.
let _ = self
.txn
.txn_execute_renew_on_timeout(|_| unsafe { ffi::mdbx_cursor_close(self.cursor) });
}
}

View File

@ -112,6 +112,18 @@ where
self.inner.txn_execute(f)
}
/// Executes the given closure once the lock on the transaction is acquired. If the transaction
/// is timed out, it will be renewed first.
///
/// Returns the result of the closure or an error if the transaction renewal fails.
#[inline]
pub(crate) fn txn_execute_renew_on_timeout<F, T>(&self, f: F) -> Result<T>
where
F: FnOnce(*mut ffi::MDBX_txn) -> T,
{
self.inner.txn_execute_renew_on_timeout(f)
}
/// Returns a copy of the raw pointer to the underlying MDBX transaction.
#[doc(hidden)]
#[cfg(test)]
@ -321,6 +333,14 @@ where
{
self.txn.txn_execute_fail_on_timeout(f)
}
#[inline]
fn txn_execute_renew_on_timeout<F, T>(&self, f: F) -> Result<T>
where
F: FnOnce(*mut ffi::MDBX_txn) -> T,
{
self.txn.txn_execute_renew_on_timeout(f)
}
}
impl<K> Drop for TransactionInner<K>
@ -596,7 +616,7 @@ impl TransactionPtr {
///
/// Returns the result of the closure or an error if the transaction renewal fails.
#[inline]
fn txn_execute_renew_on_timeout<F, T>(&self, f: F) -> Result<T>
pub(crate) fn txn_execute_renew_on_timeout<F, T>(&self, f: F) -> Result<T>
where
F: FnOnce(*mut ffi::MDBX_txn) -> T,
{