Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-cpython/src/ref_sharing.rs @ 43173:070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
The goal of this series is to encapsulate more "py_shared" thingy and
reduce the size of the macro, which is hard to debug.
Since py_shared_state manages the borrowing state of the object owned by
PySharedRefCell, this change makes more sense. If a PyObject has more than
one data to be leaked into Python world, each PySharedState should incref
the parent PyObject, and keep track of the corresponding borrowing state.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 14 Sep 2019 23:01:51 +0900 |
parents | fdfe5cfb3723 |
children | 1c675c5fe5fe |
line wrap: on
line diff
--- a/rust/hg-cpython/src/ref_sharing.rs Thu Oct 10 21:37:12 2019 +0200 +++ b/rust/hg-cpython/src/ref_sharing.rs Sat Sep 14 23:01:51 2019 +0900 @@ -27,7 +27,7 @@ use std::cell::{Cell, Ref, RefCell, RefMut}; /// Manages the shared state between Python and Rust -#[derive(Default)] +#[derive(Debug, Default)] pub struct PySharedState { leak_count: Cell<usize>, mutably_borrowed: Cell<bool>, @@ -118,12 +118,14 @@ #[derive(Debug)] pub struct PySharedRefCell<T> { inner: RefCell<T>, + pub py_shared_state: PySharedState, // TODO: remove pub } impl<T> PySharedRefCell<T> { - pub const fn new(value: T) -> PySharedRefCell<T> { + pub fn new(value: T) -> PySharedRefCell<T> { Self { inner: RefCell::new(value), + py_shared_state: PySharedState::default(), } } @@ -193,12 +195,6 @@ /// /// # Warning /// -/// The targeted `py_class!` needs to have the -/// `data py_shared_state: PySharedState;` data attribute to compile. -/// A better, more complicated macro is needed to automatically insert it, -/// but this one is not yet really battle tested (what happens when -/// multiple references are needed?). See the example below. -/// /// TODO allow Python container types: for now, integration with the garbage /// collector does not extend to Rust structs holding references to Python /// objects. Should the need surface, `__traverse__` and `__clear__` will @@ -223,7 +219,6 @@ /// /// py_class!(pub class MyType |py| { /// data inner: PySharedRefCell<MyStruct>; -/// data py_shared_state: PySharedState; /// }); /// /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); @@ -244,7 +239,7 @@ // assert $data_member type use crate::ref_sharing::PySharedRefCell; let data: &PySharedRefCell<_> = self.$data_member(py); - self.py_shared_state(py) + data.py_shared_state .borrow_mut(py, unsafe { data.borrow_mut() }) } @@ -263,7 +258,7 @@ use crate::ref_sharing::PySharedRefCell; let data: &PySharedRefCell<_> = self.$data_member(py); let static_ref = - self.py_shared_state(py).leak_immutable(py, data)?; + data.py_shared_state.leak_immutable(py, data)?; let leak_handle = $leaked::new(py, self); Ok((leak_handle, static_ref)) } @@ -292,7 +287,7 @@ fn drop(&mut self) { let gil = Python::acquire_gil(); let py = gil.python(); - let state = self.inner.py_shared_state(py); + let state = &self.inner.$data_member(py).py_shared_state; unsafe { state.decrease_leak_count(py, false); } @@ -324,7 +319,6 @@ /// /// py_class!(pub class MyType |py| { /// data inner: PySharedRefCell<MyStruct>; -/// data py_shared_state: PySharedState; /// /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };