##// END OF EJS Templates
rust-cpython: drop manual management of mutably_borrowed...
Yuya Nishihara -
r43609:6c0e4787 default
parent child Browse files
Show More
@@ -24,7 +24,7 b''
24
24
25 use crate::exceptions::AlreadyBorrowed;
25 use crate::exceptions::AlreadyBorrowed;
26 use cpython::{exc, PyClone, PyErr, PyObject, PyResult, Python};
26 use cpython::{exc, PyClone, PyErr, PyObject, PyResult, Python};
27 use std::cell::{Cell, Ref, RefCell, RefMut};
27 use std::cell::{Ref, RefCell, RefMut};
28 use std::ops::{Deref, DerefMut};
28 use std::ops::{Deref, DerefMut};
29 use std::sync::atomic::{AtomicUsize, Ordering};
29 use std::sync::atomic::{AtomicUsize, Ordering};
30
30
@@ -48,7 +48,6 b' use std::sync::atomic::{AtomicUsize, Ord'
48 /// `generation` at the time of `leak_immutable()`.
48 /// `generation` at the time of `leak_immutable()`.
49 #[derive(Debug, Default)]
49 #[derive(Debug, Default)]
50 struct PySharedState {
50 struct PySharedState {
51 mutably_borrowed: Cell<bool>,
52 // The counter variable could be Cell<usize> since any operation on
51 // The counter variable could be Cell<usize> since any operation on
53 // PySharedState is synchronized by the GIL, but being "atomic" makes
52 // PySharedState is synchronized by the GIL, but being "atomic" makes
54 // PySharedState inherently Sync. The ordering requirement doesn't
53 // PySharedState inherently Sync. The ordering requirement doesn't
@@ -57,26 +56,14 b' struct PySharedState {'
57 generation: AtomicUsize,
56 generation: AtomicUsize,
58 }
57 }
59
58
60 // &PySharedState can be Send because any access to inner cells is
61 // synchronized by the GIL.
62 unsafe impl Sync for PySharedState {}
63
64 impl PySharedState {
59 impl PySharedState {
65 fn borrow_mut<'a, T>(
60 fn borrow_mut<'a, T>(
66 &'a self,
61 &'a self,
67 py: Python<'a>,
62 py: Python<'a>,
68 pyrefmut: RefMut<'a, T>,
63 pyrefmut: RefMut<'a, T>,
69 ) -> PyResult<PyRefMut<'a, T>> {
64 ) -> PyResult<PyRefMut<'a, T>> {
70 if self.mutably_borrowed.get() {
71 return Err(AlreadyBorrowed::new(
72 py,
73 "Cannot borrow mutably while there exists another \
74 mutable reference in a Python object",
75 ));
76 }
77 match self.current_borrow_count(py) {
65 match self.current_borrow_count(py) {
78 0 => {
66 0 => {
79 self.mutably_borrowed.replace(true);
80 // Note that this wraps around to the same value if mutably
67 // Note that this wraps around to the same value if mutably
81 // borrowed more than usize::MAX times, which wouldn't happen
68 // borrowed more than usize::MAX times, which wouldn't happen
82 // in practice.
69 // in practice.
@@ -100,16 +87,9 b' impl PySharedState {'
100 /// extended. Do not call this function directly.
87 /// extended. Do not call this function directly.
101 unsafe fn leak_immutable<T>(
88 unsafe fn leak_immutable<T>(
102 &self,
89 &self,
103 py: Python,
90 _py: Python,
104 data: Ref<T>,
91 data: Ref<T>,
105 ) -> PyResult<(&'static T, &'static PySharedState)> {
92 ) -> PyResult<(&'static T, &'static PySharedState)> {
106 if self.mutably_borrowed.get() {
107 return Err(AlreadyBorrowed::new(
108 py,
109 "Cannot borrow immutably while there is a \
110 mutable reference in Python objects",
111 ));
112 }
113 let ptr: *const T = &*data;
93 let ptr: *const T = &*data;
114 let state_ptr: *const PySharedState = self;
94 let state_ptr: *const PySharedState = self;
115 Ok((&*ptr, &*state_ptr))
95 Ok((&*ptr, &*state_ptr))
@@ -130,20 +110,6 b' impl PySharedState {'
130 assert!(prev_count > 0);
110 assert!(prev_count > 0);
131 }
111 }
132
112
133 /// # Safety
134 ///
135 /// It's up to you to make sure the reference is about to be deleted
136 /// when updating the leak count.
137 fn decrease_leak_count(&self, py: Python, mutable: bool) {
138 if mutable {
139 assert_eq!(self.current_borrow_count(py), 0);
140 assert!(self.mutably_borrowed.get());
141 self.mutably_borrowed.replace(false);
142 } else {
143 unimplemented!();
144 }
145 }
146
147 fn current_generation(&self, _py: Python) -> usize {
113 fn current_generation(&self, _py: Python) -> usize {
148 self.generation.load(Ordering::Relaxed)
114 self.generation.load(Ordering::Relaxed)
149 }
115 }
@@ -262,23 +228,19 b" impl<'a, T> PySharedRef<'a, T> {"
262
228
263 /// Holds a mutable reference to data shared between Python and Rust.
229 /// Holds a mutable reference to data shared between Python and Rust.
264 pub struct PyRefMut<'a, T> {
230 pub struct PyRefMut<'a, T> {
265 py: Python<'a>,
266 inner: RefMut<'a, T>,
231 inner: RefMut<'a, T>,
267 py_shared_state: &'a PySharedState,
268 }
232 }
269
233
270 impl<'a, T> PyRefMut<'a, T> {
234 impl<'a, T> PyRefMut<'a, T> {
271 // Must be constructed by PySharedState after checking its leak_count.
235 // Must be constructed by PySharedState after checking its leak_count.
272 // Otherwise, drop() would incorrectly update the state.
236 // Otherwise, drop() would incorrectly update the state.
273 fn new(
237 fn new(
274 py: Python<'a>,
238 _py: Python<'a>,
275 inner: RefMut<'a, T>,
239 inner: RefMut<'a, T>,
276 py_shared_state: &'a PySharedState,
240 _py_shared_state: &'a PySharedState,
277 ) -> Self {
241 ) -> Self {
278 Self {
242 Self {
279 py,
280 inner,
243 inner,
281 py_shared_state,
282 }
244 }
283 }
245 }
284 }
246 }
@@ -296,12 +258,6 b" impl<'a, T> std::ops::DerefMut for PyRef"
296 }
258 }
297 }
259 }
298
260
299 impl<'a, T> Drop for PyRefMut<'a, T> {
300 fn drop(&mut self) {
301 self.py_shared_state.decrease_leak_count(self.py, true);
302 }
303 }
304
305 /// Allows a `py_class!` generated struct to share references to one of its
261 /// Allows a `py_class!` generated struct to share references to one of its
306 /// data members with Python.
262 /// data members with Python.
307 ///
263 ///
General Comments 0
You need to be logged in to leave comments. Login now