##// END OF EJS Templates
rust-cpython: move py_shared_state to PySharedRefCell object...
Yuya Nishihara -
r43443:070a3873 default
parent child Browse files
Show More
@@ -16,10 +16,7 b' use cpython::{'
16 Python,
16 Python,
17 };
17 };
18
18
19 use crate::{
19 use crate::{dirstate::extract_dirstate, ref_sharing::PySharedRefCell};
20 dirstate::extract_dirstate,
21 ref_sharing::{PySharedRefCell, PySharedState},
22 };
23 use hg::{
20 use hg::{
24 utils::hg_path::{HgPath, HgPathBuf},
21 utils::hg_path::{HgPath, HgPathBuf},
25 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
22 DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError,
@@ -28,7 +25,6 b' use hg::{'
28
25
29 py_class!(pub class Dirs |py| {
26 py_class!(pub class Dirs |py| {
30 data inner: PySharedRefCell<DirsMultiset>;
27 data inner: PySharedRefCell<DirsMultiset>;
31 data py_shared_state: PySharedState;
32
28
33 // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
29 // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
34 // a `list`)
30 // a `list`)
@@ -65,7 +61,6 b' py_class!(pub class Dirs |py| {'
65 Self::create_instance(
61 Self::create_instance(
66 py,
62 py,
67 PySharedRefCell::new(inner),
63 PySharedRefCell::new(inner),
68 PySharedState::default()
69 )
64 )
70 }
65 }
71
66
@@ -115,11 +110,7 b' py_shared_ref!(Dirs, DirsMultiset, inner'
115
110
116 impl Dirs {
111 impl Dirs {
117 pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
112 pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
118 Self::create_instance(
113 Self::create_instance(py, PySharedRefCell::new(d))
119 py,
120 PySharedRefCell::new(d),
121 PySharedState::default(),
122 )
123 }
114 }
124
115
125 fn translate_key(
116 fn translate_key(
@@ -21,7 +21,7 b' use libc::c_char;'
21 use crate::{
21 use crate::{
22 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
22 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
23 dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs},
23 dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs},
24 ref_sharing::{PySharedRefCell, PySharedState},
24 ref_sharing::PySharedRefCell,
25 };
25 };
26 use hg::{
26 use hg::{
27 utils::hg_path::{HgPath, HgPathBuf},
27 utils::hg_path::{HgPath, HgPathBuf},
@@ -44,14 +44,12 b' use hg::{'
44 // leaks, with all methods that go along for reference sharing.
44 // leaks, with all methods that go along for reference sharing.
45 py_class!(pub class DirstateMap |py| {
45 py_class!(pub class DirstateMap |py| {
46 data inner: PySharedRefCell<RustDirstateMap>;
46 data inner: PySharedRefCell<RustDirstateMap>;
47 data py_shared_state: PySharedState;
48
47
49 def __new__(_cls, _root: PyObject) -> PyResult<Self> {
48 def __new__(_cls, _root: PyObject) -> PyResult<Self> {
50 let inner = RustDirstateMap::default();
49 let inner = RustDirstateMap::default();
51 Self::create_instance(
50 Self::create_instance(
52 py,
51 py,
53 PySharedRefCell::new(inner),
52 PySharedRefCell::new(inner),
54 PySharedState::default()
55 )
53 )
56 }
54 }
57
55
@@ -27,7 +27,7 b' use cpython::{PyResult, Python};'
27 use std::cell::{Cell, Ref, RefCell, RefMut};
27 use std::cell::{Cell, Ref, RefCell, RefMut};
28
28
29 /// Manages the shared state between Python and Rust
29 /// Manages the shared state between Python and Rust
30 #[derive(Default)]
30 #[derive(Debug, Default)]
31 pub struct PySharedState {
31 pub struct PySharedState {
32 leak_count: Cell<usize>,
32 leak_count: Cell<usize>,
33 mutably_borrowed: Cell<bool>,
33 mutably_borrowed: Cell<bool>,
@@ -118,12 +118,14 b' impl PySharedState {'
118 #[derive(Debug)]
118 #[derive(Debug)]
119 pub struct PySharedRefCell<T> {
119 pub struct PySharedRefCell<T> {
120 inner: RefCell<T>,
120 inner: RefCell<T>,
121 pub py_shared_state: PySharedState, // TODO: remove pub
121 }
122 }
122
123
123 impl<T> PySharedRefCell<T> {
124 impl<T> PySharedRefCell<T> {
124 pub const fn new(value: T) -> PySharedRefCell<T> {
125 pub fn new(value: T) -> PySharedRefCell<T> {
125 Self {
126 Self {
126 inner: RefCell::new(value),
127 inner: RefCell::new(value),
128 py_shared_state: PySharedState::default(),
127 }
129 }
128 }
130 }
129
131
@@ -193,12 +195,6 b" impl<'a, T> Drop for PyRefMut<'a, T> {"
193 ///
195 ///
194 /// # Warning
196 /// # Warning
195 ///
197 ///
196 /// The targeted `py_class!` needs to have the
197 /// `data py_shared_state: PySharedState;` data attribute to compile.
198 /// A better, more complicated macro is needed to automatically insert it,
199 /// but this one is not yet really battle tested (what happens when
200 /// multiple references are needed?). See the example below.
201 ///
202 /// TODO allow Python container types: for now, integration with the garbage
198 /// TODO allow Python container types: for now, integration with the garbage
203 /// collector does not extend to Rust structs holding references to Python
199 /// collector does not extend to Rust structs holding references to Python
204 /// objects. Should the need surface, `__traverse__` and `__clear__` will
200 /// objects. Should the need surface, `__traverse__` and `__clear__` will
@@ -223,7 +219,6 b" impl<'a, T> Drop for PyRefMut<'a, T> {"
223 ///
219 ///
224 /// py_class!(pub class MyType |py| {
220 /// py_class!(pub class MyType |py| {
225 /// data inner: PySharedRefCell<MyStruct>;
221 /// data inner: PySharedRefCell<MyStruct>;
226 /// data py_shared_state: PySharedState;
227 /// });
222 /// });
228 ///
223 ///
229 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef);
224 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef);
@@ -244,7 +239,7 b' macro_rules! py_shared_ref {'
244 // assert $data_member type
239 // assert $data_member type
245 use crate::ref_sharing::PySharedRefCell;
240 use crate::ref_sharing::PySharedRefCell;
246 let data: &PySharedRefCell<_> = self.$data_member(py);
241 let data: &PySharedRefCell<_> = self.$data_member(py);
247 self.py_shared_state(py)
242 data.py_shared_state
248 .borrow_mut(py, unsafe { data.borrow_mut() })
243 .borrow_mut(py, unsafe { data.borrow_mut() })
249 }
244 }
250
245
@@ -263,7 +258,7 b' macro_rules! py_shared_ref {'
263 use crate::ref_sharing::PySharedRefCell;
258 use crate::ref_sharing::PySharedRefCell;
264 let data: &PySharedRefCell<_> = self.$data_member(py);
259 let data: &PySharedRefCell<_> = self.$data_member(py);
265 let static_ref =
260 let static_ref =
266 self.py_shared_state(py).leak_immutable(py, data)?;
261 data.py_shared_state.leak_immutable(py, data)?;
267 let leak_handle = $leaked::new(py, self);
262 let leak_handle = $leaked::new(py, self);
268 Ok((leak_handle, static_ref))
263 Ok((leak_handle, static_ref))
269 }
264 }
@@ -292,7 +287,7 b' macro_rules! py_shared_ref {'
292 fn drop(&mut self) {
287 fn drop(&mut self) {
293 let gil = Python::acquire_gil();
288 let gil = Python::acquire_gil();
294 let py = gil.python();
289 let py = gil.python();
295 let state = self.inner.py_shared_state(py);
290 let state = &self.inner.$data_member(py).py_shared_state;
296 unsafe {
291 unsafe {
297 state.decrease_leak_count(py, false);
292 state.decrease_leak_count(py, false);
298 }
293 }
@@ -324,7 +319,6 b' macro_rules! py_shared_ref {'
324 ///
319 ///
325 /// py_class!(pub class MyType |py| {
320 /// py_class!(pub class MyType |py| {
326 /// data inner: PySharedRefCell<MyStruct>;
321 /// data inner: PySharedRefCell<MyStruct>;
327 /// data py_shared_state: PySharedState;
328 ///
322 ///
329 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
323 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
330 /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
324 /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
General Comments 0
You need to be logged in to leave comments. Login now