changeset 44279:bafdaf4858d8

rust-cpython: inline PySharedState::try_borrow_mut() Since the core borrowing/leaking logic has been moved to PySharedRef* and PyLeaked*, it doesn't make sense that PySharedState had a function named "try_borrow_mut". Let's turn it into a pure data struct.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 19 Oct 2019 16:34:02 +0900
parents 2a24ead003f0
children f015d679f08c
files rust/hg-cpython/src/ref_sharing.rs
diffstat 1 files changed, 16 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-cpython/src/ref_sharing.rs	Sat Oct 12 23:34:05 2019 +0900
+++ b/rust/hg-cpython/src/ref_sharing.rs	Sat Oct 19 16:34:02 2019 +0900
@@ -57,26 +57,6 @@
 }
 
 impl PySharedState {
-    fn try_borrow_mut<'a, T>(
-        &'a self,
-        py: Python<'a>,
-        pyrefmut: RefMut<'a, T>,
-    ) -> PyResult<RefMut<'a, T>> {
-        match self.current_borrow_count(py) {
-            0 => {
-                // Note that this wraps around to the same value if mutably
-                // borrowed more than usize::MAX times, which wouldn't happen
-                // in practice.
-                self.generation.fetch_add(1, Ordering::Relaxed);
-                Ok(pyrefmut)
-            }
-            _ => Err(AlreadyBorrowed::new(
-                py,
-                "Cannot borrow mutably while immutably borrowed",
-            )),
-        }
-    }
-
     /// Return a reference to the wrapped data and its state with an
     /// artificial static lifetime.
     /// We need to be protected by the GIL for thread-safety.
@@ -113,6 +93,14 @@
     fn current_generation(&self, _py: Python) -> usize {
         self.generation.load(Ordering::Relaxed)
     }
+
+    fn increment_generation(&self, py: Python) {
+        assert_eq!(self.current_borrow_count(py), 0);
+        // Note that this wraps around to the same value if mutably
+        // borrowed more than usize::MAX times, which wouldn't happen
+        // in practice.
+        self.generation.fetch_add(1, Ordering::Relaxed);
+    }
 }
 
 /// Helper to keep the borrow count updated while the shared object is
@@ -170,11 +158,18 @@
         &'a self,
         py: Python<'a>,
     ) -> PyResult<RefMut<'a, T>> {
+        if self.py_shared_state.current_borrow_count(py) > 0 {
+            return Err(AlreadyBorrowed::new(
+                py,
+                "Cannot borrow mutably while immutably borrowed",
+            ));
+        }
         let inner_ref = self
             .inner
             .try_borrow_mut()
             .map_err(|e| AlreadyBorrowed::new(py, e.to_string()))?;
-        self.py_shared_state.try_borrow_mut(py, inner_ref)
+        self.py_shared_state.increment_generation(py);
+        Ok(inner_ref)
     }
 }