# HG changeset patch # User Georges Racinet # Date 1735143460 -3600 # Node ID e29e75e8328c04d3700af074ae221efbf4aa84ef # Parent e5f89bd1a5eedc95a7bb59aa245ac3271b432d7d 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. diff -r e5f89bd1a5ee -r e29e75e8328c rust/hg-pyo3/src/revlog/mod.rs --- 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, + ) -> PyResult, + ) -> PyResult { + 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( slf: &Bound<'_, Self>, f: impl FnOnce(&Index) -> PyResult, @@ -265,6 +285,14 @@ Self::with_core_read(slf, |_, guard| f(&guard.index)) } + #[allow(dead_code)] + fn with_index_write( + slf: &Bound<'_, Self>, + f: impl FnOnce(&mut Index) -> PyResult, + ) -> PyResult { + 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( + slf: &Bound<'_, Self>, + f: impl FnOnce(&mut Index, &mut CoreNodeTree) -> PyResult, + ) -> PyResult { + 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`] ///