rust-pyo3-revlog: index and notetree writing accessors
It works in the same way as their reading counterparts, given that
we are leveraging the inner mutability of the `PyShareable` for the index
and of the main object for the nodetree.
--- a/rust/hg-pyo3/src/revlog/mod.rs Wed Dec 25 17:15:35 2024 +0100
+++ b/rust/hg-pyo3/src/revlog/mod.rs Wed Dec 25 17:17:40 2024 +0100
@@ -14,7 +14,7 @@
use std::sync::{
atomic::{AtomicUsize, Ordering},
- RwLock, RwLockReadGuard,
+ RwLock, RwLockReadGuard, RwLockWriteGuard,
};
use hg::{
@@ -258,6 +258,26 @@
f(&self_ref, guard)
}
+ #[allow(dead_code)]
+ /// Take the lock on `slf.irl` for writing and call a closure.
+ ///
+ /// See [`Self::with_core_read`] for more explanations.
+ fn with_core_write<'py, T>(
+ slf: &Bound<'py, Self>,
+ f: impl FnOnce(
+ &PyRef<'py, Self>,
+ RwLockWriteGuard<CoreInnerRevlog>,
+ ) -> PyResult<T>,
+ ) -> PyResult<T> {
+ let self_ref = slf.borrow();
+ // Safety: the owner is the right one. We will anyway
+ // not actually `share` it. Perhaps pyo3-sharedref should provide
+ // something less scary for this kind of usage.
+ let shareable_ref = unsafe { self_ref.irl.borrow_with_owner(slf) };
+ let guard = shareable_ref.try_write().map_err(map_try_lock_error)?;
+ f(&self_ref, guard)
+ }
+
fn with_index_read<T>(
slf: &Bound<'_, Self>,
f: impl FnOnce(&Index) -> PyResult<T>,
@@ -265,6 +285,14 @@
Self::with_core_read(slf, |_, guard| f(&guard.index))
}
+ #[allow(dead_code)]
+ fn with_index_write<T>(
+ slf: &Bound<'_, Self>,
+ f: impl FnOnce(&mut Index) -> PyResult<T>,
+ ) -> PyResult<T> {
+ Self::with_core_write(slf, |_, mut guard| f(&mut guard.index))
+ }
+
/// Lock `slf` for reading and execute a closure on its [`Index`] and
/// [`NodeTree`]
///
@@ -282,6 +310,22 @@
})
}
+ #[allow(dead_code)]
+ fn with_index_nt_write<T>(
+ slf: &Bound<'_, Self>,
+ f: impl FnOnce(&mut Index, &mut CoreNodeTree) -> PyResult<T>,
+ ) -> PyResult<T> {
+ Self::with_core_write(slf, |self_ref, mut guard| {
+ let idx = &mut guard.index;
+ let mut nt = self_ref
+ .get_nodetree(idx)?
+ .write()
+ .map_err(map_lock_error)?;
+ let nt = nt.as_mut().expect("nodetree should be set");
+ f(idx, nt)
+ })
+ }
+
/// Fill a [`CoreNodeTree`] by doing a full iteration on the given
/// [`Index`]
///