Show More
@@ -16,10 +16,7 b' use cpython::{' | |||
|
16 | 16 | Python, |
|
17 | 17 | }; |
|
18 | 18 | |
|
19 | use crate::{ | |
|
20 | dirstate::extract_dirstate, | |
|
21 | ref_sharing::{PySharedRefCell, PySharedState}, | |
|
22 | }; | |
|
19 | use crate::{dirstate::extract_dirstate, ref_sharing::PySharedRefCell}; | |
|
23 | 20 | use hg::{ |
|
24 | 21 | utils::hg_path::{HgPath, HgPathBuf}, |
|
25 | 22 | DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError, |
@@ -28,7 +25,6 b' use hg::{' | |||
|
28 | 25 | |
|
29 | 26 | py_class!(pub class Dirs |py| { |
|
30 | 27 | data inner: PySharedRefCell<DirsMultiset>; |
|
31 | data py_shared_state: PySharedState; | |
|
32 | 28 | |
|
33 | 29 | // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes |
|
34 | 30 | // a `list`) |
@@ -65,7 +61,6 b' py_class!(pub class Dirs |py| {' | |||
|
65 | 61 | Self::create_instance( |
|
66 | 62 | py, |
|
67 | 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 | 111 | impl Dirs { |
|
117 | 112 | pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> { |
|
118 | Self::create_instance( | |
|
119 | py, | |
|
120 | PySharedRefCell::new(d), | |
|
121 | PySharedState::default(), | |
|
122 | ) | |
|
113 | Self::create_instance(py, PySharedRefCell::new(d)) | |
|
123 | 114 | } |
|
124 | 115 | |
|
125 | 116 | fn translate_key( |
@@ -21,7 +21,7 b' use libc::c_char;' | |||
|
21 | 21 | use crate::{ |
|
22 | 22 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
|
23 | 23 | dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs}, |
|
24 |
ref_sharing:: |
|
|
24 | ref_sharing::PySharedRefCell, | |
|
25 | 25 | }; |
|
26 | 26 | use hg::{ |
|
27 | 27 | utils::hg_path::{HgPath, HgPathBuf}, |
@@ -44,14 +44,12 b' use hg::{' | |||
|
44 | 44 | // leaks, with all methods that go along for reference sharing. |
|
45 | 45 | py_class!(pub class DirstateMap |py| { |
|
46 | 46 | data inner: PySharedRefCell<RustDirstateMap>; |
|
47 | data py_shared_state: PySharedState; | |
|
48 | 47 | |
|
49 | 48 | def __new__(_cls, _root: PyObject) -> PyResult<Self> { |
|
50 | 49 | let inner = RustDirstateMap::default(); |
|
51 | 50 | Self::create_instance( |
|
52 | 51 | py, |
|
53 | 52 | PySharedRefCell::new(inner), |
|
54 | PySharedState::default() | |
|
55 | 53 | ) |
|
56 | 54 | } |
|
57 | 55 |
@@ -27,7 +27,7 b' use cpython::{PyResult, Python};' | |||
|
27 | 27 | use std::cell::{Cell, Ref, RefCell, RefMut}; |
|
28 | 28 | |
|
29 | 29 | /// Manages the shared state between Python and Rust |
|
30 | #[derive(Default)] | |
|
30 | #[derive(Debug, Default)] | |
|
31 | 31 | pub struct PySharedState { |
|
32 | 32 | leak_count: Cell<usize>, |
|
33 | 33 | mutably_borrowed: Cell<bool>, |
@@ -118,12 +118,14 b' impl PySharedState {' | |||
|
118 | 118 | #[derive(Debug)] |
|
119 | 119 | pub struct PySharedRefCell<T> { |
|
120 | 120 | inner: RefCell<T>, |
|
121 | pub py_shared_state: PySharedState, // TODO: remove pub | |
|
121 | 122 | } |
|
122 | 123 | |
|
123 | 124 | impl<T> PySharedRefCell<T> { |
|
124 |
pub |
|
|
125 | pub fn new(value: T) -> PySharedRefCell<T> { | |
|
125 | 126 | Self { |
|
126 | 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 | 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 | 198 | /// TODO allow Python container types: for now, integration with the garbage |
|
203 | 199 | /// collector does not extend to Rust structs holding references to Python |
|
204 | 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 | 220 | /// py_class!(pub class MyType |py| { |
|
225 | 221 | /// data inner: PySharedRefCell<MyStruct>; |
|
226 | /// data py_shared_state: PySharedState; | |
|
227 | 222 | /// }); |
|
228 | 223 | /// |
|
229 | 224 | /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); |
@@ -244,7 +239,7 b' macro_rules! py_shared_ref {' | |||
|
244 | 239 | // assert $data_member type |
|
245 | 240 | use crate::ref_sharing::PySharedRefCell; |
|
246 | 241 | let data: &PySharedRefCell<_> = self.$data_member(py); |
|
247 |
|
|
|
242 | data.py_shared_state | |
|
248 | 243 | .borrow_mut(py, unsafe { data.borrow_mut() }) |
|
249 | 244 | } |
|
250 | 245 | |
@@ -263,7 +258,7 b' macro_rules! py_shared_ref {' | |||
|
263 | 258 | use crate::ref_sharing::PySharedRefCell; |
|
264 | 259 | let data: &PySharedRefCell<_> = self.$data_member(py); |
|
265 | 260 | let static_ref = |
|
266 |
|
|
|
261 | data.py_shared_state.leak_immutable(py, data)?; | |
|
267 | 262 | let leak_handle = $leaked::new(py, self); |
|
268 | 263 | Ok((leak_handle, static_ref)) |
|
269 | 264 | } |
@@ -292,7 +287,7 b' macro_rules! py_shared_ref {' | |||
|
292 | 287 | fn drop(&mut self) { |
|
293 | 288 | let gil = Python::acquire_gil(); |
|
294 | 289 | let py = gil.python(); |
|
295 |
let state = self.inner. |
|
|
290 | let state = &self.inner.$data_member(py).py_shared_state; | |
|
296 | 291 | unsafe { |
|
297 | 292 | state.decrease_leak_count(py, false); |
|
298 | 293 | } |
@@ -324,7 +319,6 b' macro_rules! py_shared_ref {' | |||
|
324 | 319 | /// |
|
325 | 320 | /// py_class!(pub class MyType |py| { |
|
326 | 321 | /// data inner: PySharedRefCell<MyStruct>; |
|
327 | /// data py_shared_state: PySharedState; | |
|
328 | 322 | /// |
|
329 | 323 | /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
|
330 | 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