rust/hg-cpython/src/ref_sharing.rs
changeset 44204 bafdaf4858d8
parent 44203 2a24ead003f0
child 44205 f015d679f08c
equal deleted inserted replaced
44203:2a24ead003f0 44204:bafdaf4858d8
    55     borrow_count: AtomicUsize,
    55     borrow_count: AtomicUsize,
    56     generation: AtomicUsize,
    56     generation: AtomicUsize,
    57 }
    57 }
    58 
    58 
    59 impl PySharedState {
    59 impl PySharedState {
    60     fn try_borrow_mut<'a, T>(
       
    61         &'a self,
       
    62         py: Python<'a>,
       
    63         pyrefmut: RefMut<'a, T>,
       
    64     ) -> PyResult<RefMut<'a, T>> {
       
    65         match self.current_borrow_count(py) {
       
    66             0 => {
       
    67                 // Note that this wraps around to the same value if mutably
       
    68                 // borrowed more than usize::MAX times, which wouldn't happen
       
    69                 // in practice.
       
    70                 self.generation.fetch_add(1, Ordering::Relaxed);
       
    71                 Ok(pyrefmut)
       
    72             }
       
    73             _ => Err(AlreadyBorrowed::new(
       
    74                 py,
       
    75                 "Cannot borrow mutably while immutably borrowed",
       
    76             )),
       
    77         }
       
    78     }
       
    79 
       
    80     /// Return a reference to the wrapped data and its state with an
    60     /// Return a reference to the wrapped data and its state with an
    81     /// artificial static lifetime.
    61     /// artificial static lifetime.
    82     /// We need to be protected by the GIL for thread-safety.
    62     /// We need to be protected by the GIL for thread-safety.
    83     ///
    63     ///
    84     /// # Safety
    64     /// # Safety
   111     }
    91     }
   112 
    92 
   113     fn current_generation(&self, _py: Python) -> usize {
    93     fn current_generation(&self, _py: Python) -> usize {
   114         self.generation.load(Ordering::Relaxed)
    94         self.generation.load(Ordering::Relaxed)
   115     }
    95     }
       
    96 
       
    97     fn increment_generation(&self, py: Python) {
       
    98         assert_eq!(self.current_borrow_count(py), 0);
       
    99         // Note that this wraps around to the same value if mutably
       
   100         // borrowed more than usize::MAX times, which wouldn't happen
       
   101         // in practice.
       
   102         self.generation.fetch_add(1, Ordering::Relaxed);
       
   103     }
   116 }
   104 }
   117 
   105 
   118 /// Helper to keep the borrow count updated while the shared object is
   106 /// Helper to keep the borrow count updated while the shared object is
   119 /// immutably borrowed without using the `RefCell` interface.
   107 /// immutably borrowed without using the `RefCell` interface.
   120 struct BorrowPyShared<'a> {
   108 struct BorrowPyShared<'a> {
   168 
   156 
   169     fn try_borrow_mut<'a>(
   157     fn try_borrow_mut<'a>(
   170         &'a self,
   158         &'a self,
   171         py: Python<'a>,
   159         py: Python<'a>,
   172     ) -> PyResult<RefMut<'a, T>> {
   160     ) -> PyResult<RefMut<'a, T>> {
       
   161         if self.py_shared_state.current_borrow_count(py) > 0 {
       
   162             return Err(AlreadyBorrowed::new(
       
   163                 py,
       
   164                 "Cannot borrow mutably while immutably borrowed",
       
   165             ));
       
   166         }
   173         let inner_ref = self
   167         let inner_ref = self
   174             .inner
   168             .inner
   175             .try_borrow_mut()
   169             .try_borrow_mut()
   176             .map_err(|e| AlreadyBorrowed::new(py, e.to_string()))?;
   170             .map_err(|e| AlreadyBorrowed::new(py, e.to_string()))?;
   177         self.py_shared_state.try_borrow_mut(py, inner_ref)
   171         self.py_shared_state.increment_generation(py);
       
   172         Ok(inner_ref)
   178     }
   173     }
   179 }
   174 }
   180 
   175 
   181 /// Sharable data member of type `T` borrowed from the `PyObject`.
   176 /// Sharable data member of type `T` borrowed from the `PyObject`.
   182 pub struct PySharedRef<'a, T> {
   177 pub struct PySharedRef<'a, T> {