Show More
@@ -74,8 +74,8 b' impl PySharedState {' | |||||
74 | } |
|
74 | } | |
75 | } |
|
75 | } | |
76 |
|
76 | |||
77 |
/// Return a reference to the wrapped data |
|
77 | /// Return a reference to the wrapped data and its state with an | |
78 | /// lifetime. |
|
78 | /// artificial static lifetime. | |
79 | /// We need to be protected by the GIL for thread-safety. |
|
79 | /// We need to be protected by the GIL for thread-safety. | |
80 | /// |
|
80 | /// | |
81 | /// # Safety |
|
81 | /// # Safety | |
@@ -86,7 +86,7 b' impl PySharedState {' | |||||
86 | &self, |
|
86 | &self, | |
87 | py: Python, |
|
87 | py: Python, | |
88 | data: &PySharedRefCell<T>, |
|
88 | data: &PySharedRefCell<T>, | |
89 | ) -> PyResult<&'static T> { |
|
89 | ) -> PyResult<(&'static T, &'static PySharedState)> { | |
90 | if self.mutably_borrowed.get() { |
|
90 | if self.mutably_borrowed.get() { | |
91 | return Err(AlreadyBorrowed::new( |
|
91 | return Err(AlreadyBorrowed::new( | |
92 | py, |
|
92 | py, | |
@@ -94,9 +94,12 b' impl PySharedState {' | |||||
94 | mutable reference in Python objects", |
|
94 | mutable reference in Python objects", | |
95 | )); |
|
95 | )); | |
96 | } |
|
96 | } | |
|
97 | // TODO: it's weird that self is data.py_shared_state. Maybe we | |||
|
98 | // can move stuff to PySharedRefCell? | |||
97 | let ptr = data.as_ptr(); |
|
99 | let ptr = data.as_ptr(); | |
|
100 | let state_ptr: *const PySharedState = &data.py_shared_state; | |||
98 | self.leak_count.replace(self.leak_count.get() + 1); |
|
101 | self.leak_count.replace(self.leak_count.get() + 1); | |
99 | Ok(&*ptr) |
|
102 | Ok((&*ptr, &*state_ptr)) | |
100 | } |
|
103 | } | |
101 |
|
104 | |||
102 | /// # Safety |
|
105 | /// # Safety | |
@@ -267,9 +270,9 b' macro_rules! py_shared_ref {' | |||||
267 | // assert $data_member type |
|
270 | // assert $data_member type | |
268 | use crate::ref_sharing::PySharedRefCell; |
|
271 | use crate::ref_sharing::PySharedRefCell; | |
269 | let data: &PySharedRefCell<_> = self.$data_member(py); |
|
272 | let data: &PySharedRefCell<_> = self.$data_member(py); | |
270 | let static_ref = |
|
273 | let (static_ref, static_state_ref) = | |
271 | data.py_shared_state.leak_immutable(py, data)?; |
|
274 | data.py_shared_state.leak_immutable(py, data)?; | |
272 | let leak_handle = $leaked::new(py, self); |
|
275 | let leak_handle = $leaked::new(py, self, static_state_ref); | |
273 | Ok((leak_handle, static_ref)) |
|
276 | Ok((leak_handle, static_ref)) | |
274 | } |
|
277 | } | |
275 | } |
|
278 | } | |
@@ -280,26 +283,38 b' macro_rules! py_shared_ref {' | |||||
280 | /// In truth, this does not represent leaked references themselves; |
|
283 | /// In truth, this does not represent leaked references themselves; | |
281 | /// it is instead useful alongside them to manage them. |
|
284 | /// it is instead useful alongside them to manage them. | |
282 | pub struct $leaked { |
|
285 | pub struct $leaked { | |
283 | inner: $name, |
|
286 | _inner: $name, | |
|
287 | py_shared_state: &'static crate::ref_sharing::PySharedState, | |||
284 | } |
|
288 | } | |
285 |
|
289 | |||
286 | impl $leaked { |
|
290 | impl $leaked { | |
|
291 | /// # Safety | |||
|
292 | /// | |||
|
293 | /// The `py_shared_state` must be owned by the `inner` Python | |||
|
294 | /// object. | |||
287 | // Marked as unsafe so client code wouldn't construct $leaked |
|
295 | // Marked as unsafe so client code wouldn't construct $leaked | |
288 | // struct by mistake. Its drop() is unsafe. |
|
296 | // struct by mistake. Its drop() is unsafe. | |
289 | unsafe fn new(py: Python, inner: &$name) -> Self { |
|
297 | unsafe fn new( | |
|
298 | py: Python, | |||
|
299 | inner: &$name, | |||
|
300 | py_shared_state: &'static crate::ref_sharing::PySharedState, | |||
|
301 | ) -> Self { | |||
290 | Self { |
|
302 | Self { | |
291 | inner: inner.clone_ref(py), |
|
303 | _inner: inner.clone_ref(py), | |
|
304 | py_shared_state, | |||
292 | } |
|
305 | } | |
293 | } |
|
306 | } | |
294 | } |
|
307 | } | |
295 |
|
308 | |||
296 | impl Drop for $leaked { |
|
309 | impl Drop for $leaked { | |
297 | fn drop(&mut self) { |
|
310 | fn drop(&mut self) { | |
|
311 | // py_shared_state should be alive since we do have | |||
|
312 | // a Python reference to the owner object. Taking GIL makes | |||
|
313 | // sure that the state is only accessed by this thread. | |||
298 | let gil = Python::acquire_gil(); |
|
314 | let gil = Python::acquire_gil(); | |
299 | let py = gil.python(); |
|
315 | let py = gil.python(); | |
300 | let state = &self.inner.$data_member(py).py_shared_state; |
|
|||
301 | unsafe { |
|
316 | unsafe { | |
302 | state.decrease_leak_count(py, false); |
|
317 | self.py_shared_state.decrease_leak_count(py, false); | |
303 | } |
|
318 | } | |
304 | } |
|
319 | } | |
305 | } |
|
320 | } |
General Comments 0
You need to be logged in to leave comments.
Login now