Show More
@@ -28,7 +28,7 b' use std::cell::{Cell, Ref, RefCell, RefM' | |||||
28 |
|
28 | |||
29 | /// Manages the shared state between Python and Rust |
|
29 | /// Manages the shared state between Python and Rust | |
30 | #[derive(Debug, Default)] |
|
30 | #[derive(Debug, Default)] | |
31 |
|
|
31 | struct PySharedState { | |
32 | leak_count: Cell<usize>, |
|
32 | leak_count: Cell<usize>, | |
33 | mutably_borrowed: Cell<bool>, |
|
33 | mutably_borrowed: Cell<bool>, | |
34 | } |
|
34 | } | |
@@ -38,7 +38,7 b' pub struct PySharedState {' | |||||
38 | unsafe impl Sync for PySharedState {} |
|
38 | unsafe impl Sync for PySharedState {} | |
39 |
|
39 | |||
40 | impl PySharedState { |
|
40 | impl PySharedState { | |
41 |
|
|
41 | fn borrow_mut<'a, T>( | |
42 | &'a self, |
|
42 | &'a self, | |
43 | py: Python<'a>, |
|
43 | py: Python<'a>, | |
44 | pyrefmut: RefMut<'a, T>, |
|
44 | pyrefmut: RefMut<'a, T>, | |
@@ -82,7 +82,7 b' impl PySharedState {' | |||||
82 | /// |
|
82 | /// | |
83 | /// This is highly unsafe since the lifetime of the given data can be |
|
83 | /// This is highly unsafe since the lifetime of the given data can be | |
84 | /// extended. Do not call this function directly. |
|
84 | /// extended. Do not call this function directly. | |
85 |
|
|
85 | unsafe fn leak_immutable<T>( | |
86 | &self, |
|
86 | &self, | |
87 | py: Python, |
|
87 | py: Python, | |
88 | data: &PySharedRefCell<T>, |
|
88 | data: &PySharedRefCell<T>, | |
@@ -104,9 +104,9 b' impl PySharedState {' | |||||
104 |
|
104 | |||
105 | /// # Safety |
|
105 | /// # Safety | |
106 | /// |
|
106 | /// | |
107 |
/// It's u |
|
107 | /// It's up to you to make sure the reference is about to be deleted | |
108 | /// reference is deleted. Do not call this function directly. |
|
108 | /// when updating the leak count. | |
109 |
|
|
109 | fn decrease_leak_count(&self, _py: Python, mutable: bool) { | |
110 | if mutable { |
|
110 | if mutable { | |
111 | assert_eq!(self.leak_count.get(), 0); |
|
111 | assert_eq!(self.leak_count.get(), 0); | |
112 | assert!(self.mutably_borrowed.get()); |
|
112 | assert!(self.mutably_borrowed.get()); | |
@@ -121,7 +121,8 b' impl PySharedState {' | |||||
121 |
|
121 | |||
122 | /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. |
|
122 | /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. | |
123 | /// |
|
123 | /// | |
124 | /// Only immutable operation is allowed through this interface. |
|
124 | /// This object can be stored in a `py_class!` object as a data field. Any | |
|
125 | /// operation is allowed through the `PySharedRef` interface. | |||
125 | #[derive(Debug)] |
|
126 | #[derive(Debug)] | |
126 | pub struct PySharedRefCell<T> { |
|
127 | pub struct PySharedRefCell<T> { | |
127 | inner: RefCell<T>, |
|
128 | inner: RefCell<T>, | |
@@ -136,14 +137,14 b' impl<T> PySharedRefCell<T> {' | |||||
136 | } |
|
137 | } | |
137 | } |
|
138 | } | |
138 |
|
139 | |||
139 |
|
|
140 | fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> { | |
140 | // py_shared_state isn't involved since |
|
141 | // py_shared_state isn't involved since | |
141 | // - inner.borrow() would fail if self is mutably borrowed, |
|
142 | // - inner.borrow() would fail if self is mutably borrowed, | |
142 | // - and inner.borrow_mut() would fail while self is borrowed. |
|
143 | // - and inner.borrow_mut() would fail while self is borrowed. | |
143 | self.inner.borrow() |
|
144 | self.inner.borrow() | |
144 | } |
|
145 | } | |
145 |
|
146 | |||
146 |
|
|
147 | fn as_ptr(&self) -> *mut T { | |
147 | self.inner.as_ptr() |
|
148 | self.inner.as_ptr() | |
148 | } |
|
149 | } | |
149 |
|
150 | |||
@@ -151,10 +152,7 b' impl<T> PySharedRefCell<T> {' | |||||
151 | // inner.try_borrow_mut(). The current implementation panics if |
|
152 | // inner.try_borrow_mut(). The current implementation panics if | |
152 | // self.inner has been borrowed, but returns error if py_shared_state |
|
153 | // self.inner has been borrowed, but returns error if py_shared_state | |
153 | // refuses to borrow. |
|
154 | // refuses to borrow. | |
154 | pub fn borrow_mut<'a>( |
|
155 | fn borrow_mut<'a>(&'a self, py: Python<'a>) -> PyResult<PyRefMut<'a, T>> { | |
155 | &'a self, |
|
|||
156 | py: Python<'a>, |
|
|||
157 | ) -> PyResult<PyRefMut<'a, T>> { |
|
|||
158 | self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) |
|
156 | self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) | |
159 | } |
|
157 | } | |
160 | } |
|
158 | } | |
@@ -241,9 +239,7 b" impl<'a, T> std::ops::DerefMut for PyRef" | |||||
241 |
|
239 | |||
242 | impl<'a, T> Drop for PyRefMut<'a, T> { |
|
240 | impl<'a, T> Drop for PyRefMut<'a, T> { | |
243 | fn drop(&mut self) { |
|
241 | fn drop(&mut self) { | |
244 | unsafe { |
|
242 | self.py_shared_state.decrease_leak_count(self.py, true); | |
245 | self.py_shared_state.decrease_leak_count(self.py, true); |
|
|||
246 | } |
|
|||
247 | } |
|
243 | } | |
248 | } |
|
244 | } | |
249 |
|
245 | |||
@@ -324,9 +320,7 b' impl<T> PyLeakedRef<T> {' | |||||
324 | /// # Safety |
|
320 | /// # Safety | |
325 | /// |
|
321 | /// | |
326 | /// The `py_shared_state` must be owned by the `inner` Python object. |
|
322 | /// The `py_shared_state` must be owned by the `inner` Python object. | |
327 | // Marked as unsafe so client code wouldn't construct PyLeakedRef |
|
323 | fn new( | |
328 | // struct by mistake. Its drop() is unsafe. |
|
|||
329 | pub unsafe fn new( |
|
|||
330 | py: Python, |
|
324 | py: Python, | |
331 | inner: &PyObject, |
|
325 | inner: &PyObject, | |
332 | data: T, |
|
326 | data: T, | |
@@ -391,9 +385,7 b' impl<T> Drop for PyLeakedRef<T> {' | |||||
391 | if self.data.is_none() { |
|
385 | if self.data.is_none() { | |
392 | return; // moved to another PyLeakedRef |
|
386 | return; // moved to another PyLeakedRef | |
393 | } |
|
387 | } | |
394 | unsafe { |
|
388 | self.py_shared_state.decrease_leak_count(py, false); | |
395 | self.py_shared_state.decrease_leak_count(py, false); |
|
|||
396 | } |
|
|||
397 | } |
|
389 | } | |
398 | } |
|
390 | } | |
399 |
|
391 |
General Comments 0
You need to be logged in to leave comments.
Login now