##// END OF EJS Templates
rust-cpython: store leaked reference to PySharedState in $leaked struct...
Yuya Nishihara -
r43446:aaec70a5 default
parent child Browse files
Show More
@@ -74,8 +74,8 b' impl PySharedState {'
74 }
74 }
75 }
75 }
76
76
77 /// Return a reference to the wrapped data with an artificial static
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