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:: |
|
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 |
|
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 |
|
|
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 |
|
|
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. |
|
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