Show More
@@ -11,7 +11,8 b'' | |||
|
11 | 11 | use cpython::{PyBytes, PyClone, PyDict, PyObject, PyResult, Python}; |
|
12 | 12 | use std::cell::RefCell; |
|
13 | 13 | |
|
14 |
use crate::dirstate::dirstate_map:: |
|
|
14 | use crate::dirstate::dirstate_map::DirstateMap; | |
|
15 | use crate::ref_sharing::PyLeakedRef; | |
|
15 | 16 | use hg::{utils::hg_path::HgPathBuf, CopyMapIter}; |
|
16 | 17 | |
|
17 | 18 | py_class!(pub class CopyMap |py| { |
@@ -103,7 +104,7 b' impl CopyMap {' | |||
|
103 | 104 | |
|
104 | 105 | py_shared_iterator!( |
|
105 | 106 | CopyMapKeysIterator, |
|
106 |
|
|
|
107 | PyLeakedRef, | |
|
107 | 108 | CopyMapIter<'static>, |
|
108 | 109 | CopyMap::translate_key, |
|
109 | 110 | Option<PyBytes> |
@@ -111,7 +112,7 b' py_shared_iterator!(' | |||
|
111 | 112 | |
|
112 | 113 | py_shared_iterator!( |
|
113 | 114 | CopyMapItemsIterator, |
|
114 |
|
|
|
115 | PyLeakedRef, | |
|
115 | 116 | CopyMapIter<'static>, |
|
116 | 117 | CopyMap::translate_key_value, |
|
117 | 118 | Option<(PyBytes, PyBytes)> |
@@ -16,7 +16,8 b' use cpython::{' | |||
|
16 | 16 | Python, |
|
17 | 17 | }; |
|
18 | 18 | |
|
19 |
use crate:: |
|
|
19 | use crate::dirstate::extract_dirstate; | |
|
20 | use crate::ref_sharing::{PyLeakedRef, PySharedRefCell}; | |
|
20 | 21 | use hg::{ |
|
21 | 22 | utils::hg_path::{HgPath, HgPathBuf}, |
|
22 | 23 | DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError, |
@@ -106,7 +107,7 b' py_class!(pub class Dirs |py| {' | |||
|
106 | 107 | } |
|
107 | 108 | }); |
|
108 | 109 | |
|
109 |
py_shared_ref!(Dirs, DirsMultiset, inner |
|
|
110 | py_shared_ref!(Dirs, DirsMultiset, inner); | |
|
110 | 111 | |
|
111 | 112 | impl Dirs { |
|
112 | 113 | pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> { |
@@ -123,7 +124,7 b' impl Dirs {' | |||
|
123 | 124 | |
|
124 | 125 | py_shared_iterator!( |
|
125 | 126 | DirsMultisetKeysIterator, |
|
126 |
|
|
|
127 | PyLeakedRef, | |
|
127 | 128 | DirsMultisetIter<'static>, |
|
128 | 129 | Dirs::translate_key, |
|
129 | 130 | Option<PyBytes> |
@@ -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::PySharedRefCell, | |
|
24 | ref_sharing::{PyLeakedRef, PySharedRefCell}, | |
|
25 | 25 | }; |
|
26 | 26 | use hg::{ |
|
27 | 27 | utils::hg_path::{HgPath, HgPathBuf}, |
@@ -501,11 +501,11 b' impl DirstateMap {' | |||
|
501 | 501 | } |
|
502 | 502 | } |
|
503 | 503 | |
|
504 |
py_shared_ref!(DirstateMap, RustDirstateMap, inner |
|
|
504 | py_shared_ref!(DirstateMap, RustDirstateMap, inner); | |
|
505 | 505 | |
|
506 | 506 | py_shared_iterator!( |
|
507 | 507 | DirstateMapKeysIterator, |
|
508 |
|
|
|
508 | PyLeakedRef, | |
|
509 | 509 | StateMapIter<'static>, |
|
510 | 510 | DirstateMap::translate_key, |
|
511 | 511 | Option<PyBytes> |
@@ -513,7 +513,7 b' py_shared_iterator!(' | |||
|
513 | 513 | |
|
514 | 514 | py_shared_iterator!( |
|
515 | 515 | DirstateMapItemsIterator, |
|
516 |
|
|
|
516 | PyLeakedRef, | |
|
517 | 517 | StateMapIter<'static>, |
|
518 | 518 | DirstateMap::translate_key_value, |
|
519 | 519 | Option<(PyBytes, PyObject)> |
@@ -23,7 +23,7 b'' | |||
|
23 | 23 | //! Macros for use in the `hg-cpython` bridge library. |
|
24 | 24 | |
|
25 | 25 | use crate::exceptions::AlreadyBorrowed; |
|
26 | use cpython::{PyResult, Python}; | |
|
26 | use cpython::{PyClone, PyObject, PyResult, Python}; | |
|
27 | 27 | use std::cell::{Cell, Ref, RefCell, RefMut}; |
|
28 | 28 | |
|
29 | 29 | /// Manages the shared state between Python and Rust |
@@ -219,9 +219,6 b" impl<'a, T> Drop for PyRefMut<'a, T> {" | |||
|
219 | 219 | /// * `$inner_struct` is the identifier of the underlying Rust struct |
|
220 | 220 | /// * `$data_member` is the identifier of the data member of `$inner_struct` |
|
221 | 221 | /// that will be shared. |
|
222 | /// * `$leaked` is the identifier to give to the struct that will manage | |
|
223 | /// references to `$name`, to be used for example in other macros like | |
|
224 | /// `py_shared_iterator`. | |
|
225 | 222 | /// |
|
226 | 223 | /// # Example |
|
227 | 224 | /// |
@@ -234,14 +231,13 b" impl<'a, T> Drop for PyRefMut<'a, T> {" | |||
|
234 | 231 | /// data inner: PySharedRefCell<MyStruct>; |
|
235 | 232 | /// }); |
|
236 | 233 | /// |
|
237 |
/// py_shared_ref!(MyType, MyStruct, inner |
|
|
234 | /// py_shared_ref!(MyType, MyStruct, inner); | |
|
238 | 235 | /// ``` |
|
239 | 236 | macro_rules! py_shared_ref { |
|
240 | 237 | ( |
|
241 | 238 | $name: ident, |
|
242 | 239 | $inner_struct: ident, |
|
243 |
$data_member: ident |
|
|
244 | $leaked: ident, | |
|
240 | $data_member: ident | |
|
245 | 241 | ) => { |
|
246 | 242 | impl $name { |
|
247 | 243 | // TODO: remove this function in favor of inner(py).borrow_mut() |
@@ -266,59 +262,59 b' macro_rules! py_shared_ref {' | |||
|
266 | 262 | unsafe fn leak_immutable<'a>( |
|
267 | 263 | &'a self, |
|
268 | 264 | py: Python<'a>, |
|
269 |
) -> PyResult<( |
|
|
265 | ) -> PyResult<(PyLeakedRef, &'static $inner_struct)> { | |
|
266 | use cpython::PythonObject; | |
|
270 | 267 | // assert $data_member type |
|
271 | 268 | use crate::ref_sharing::PySharedRefCell; |
|
272 | 269 | let data: &PySharedRefCell<_> = self.$data_member(py); |
|
273 | 270 | let (static_ref, static_state_ref) = |
|
274 | 271 | data.py_shared_state.leak_immutable(py, data)?; |
|
275 |
let leak_handle = |
|
|
272 | let leak_handle = | |
|
273 | PyLeakedRef::new(py, self.as_object(), static_state_ref); | |
|
276 | 274 | Ok((leak_handle, static_ref)) |
|
277 | 275 | } |
|
278 | 276 | } |
|
277 | }; | |
|
278 | } | |
|
279 | 279 | |
|
280 |
|
|
|
281 | /// iterators. | |
|
282 | /// | |
|
283 | /// In truth, this does not represent leaked references themselves; | |
|
284 | /// it is instead useful alongside them to manage them. | |
|
285 | pub struct $leaked { | |
|
286 | _inner: $name, | |
|
287 | py_shared_state: &'static crate::ref_sharing::PySharedState, | |
|
288 | } | |
|
280 | /// Manage immutable references to `PyObject` leaked into Python iterators. | |
|
281 | /// | |
|
282 | /// In truth, this does not represent leaked references themselves; | |
|
283 | /// it is instead useful alongside them to manage them. | |
|
284 | pub struct PyLeakedRef { | |
|
285 | _inner: PyObject, | |
|
286 | py_shared_state: &'static PySharedState, | |
|
287 | } | |
|
289 | 288 | |
|
290 |
|
|
|
291 |
|
|
|
292 |
|
|
|
293 |
|
|
|
294 | /// object. | |
|
295 | // Marked as unsafe so client code wouldn't construct $leaked | |
|
296 | // struct by mistake. Its drop() is unsafe. | |
|
297 | unsafe fn new( | |
|
298 | py: Python, | |
|
299 | inner: &$name, | |
|
300 | py_shared_state: &'static crate::ref_sharing::PySharedState, | |
|
301 |
|
|
|
302 | Self { | |
|
303 | _inner: inner.clone_ref(py), | |
|
304 | py_shared_state, | |
|
305 | } | |
|
306 | } | |
|
289 | impl PyLeakedRef { | |
|
290 | /// # Safety | |
|
291 | /// | |
|
292 | /// The `py_shared_state` must be owned by the `inner` Python object. | |
|
293 | // Marked as unsafe so client code wouldn't construct PyLeakedRef | |
|
294 | // struct by mistake. Its drop() is unsafe. | |
|
295 | pub unsafe fn new( | |
|
296 | py: Python, | |
|
297 | inner: &PyObject, | |
|
298 | py_shared_state: &'static PySharedState, | |
|
299 | ) -> Self { | |
|
300 | Self { | |
|
301 | _inner: inner.clone_ref(py), | |
|
302 | py_shared_state, | |
|
307 | 303 | } |
|
304 | } | |
|
305 | } | |
|
308 | 306 | |
|
309 |
|
|
|
310 |
|
|
|
311 |
|
|
|
312 |
|
|
|
313 |
|
|
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
|
317 |
|
|
|
318 | } | |
|
319 | } | |
|
307 | impl Drop for PyLeakedRef { | |
|
308 | fn drop(&mut self) { | |
|
309 | // py_shared_state should be alive since we do have | |
|
310 | // a Python reference to the owner object. Taking GIL makes | |
|
311 | // sure that the state is only accessed by this thread. | |
|
312 | let gil = Python::acquire_gil(); | |
|
313 | let py = gil.python(); | |
|
314 | unsafe { | |
|
315 | self.py_shared_state.decrease_leak_count(py, false); | |
|
320 | 316 | } |
|
321 |
} |
|
|
317 | } | |
|
322 | 318 | } |
|
323 | 319 | |
|
324 | 320 | /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
@@ -372,7 +368,7 b' macro_rules! py_shared_ref {' | |||
|
372 | 368 | /// |
|
373 | 369 | /// py_shared_iterator!( |
|
374 | 370 | /// MyTypeItemsIterator, |
|
375 |
/// |
|
|
371 | /// PyLeakedRef, | |
|
376 | 372 | /// HashMap<'static, Vec<u8>, Vec<u8>>, |
|
377 | 373 | /// MyType::translate_key_value, |
|
378 | 374 | /// Option<(PyBytes, PyBytes)> |
@@ -381,7 +377,7 b' macro_rules! py_shared_ref {' | |||
|
381 | 377 | macro_rules! py_shared_iterator { |
|
382 | 378 | ( |
|
383 | 379 | $name: ident, |
|
384 |
$leaked: |
|
|
380 | $leaked: ty, | |
|
385 | 381 | $iterator_type: ty, |
|
386 | 382 | $success_func: expr, |
|
387 | 383 | $success_type: ty |
General Comments 0
You need to be logged in to leave comments.
Login now