Show More
@@ -12,7 +12,7 b' use cpython::{PyBytes, PyClone, PyDict, ' | |||
|
12 | 12 | use std::cell::RefCell; |
|
13 | 13 | |
|
14 | 14 | use crate::dirstate::dirstate_map::DirstateMap; |
|
15 |
use crate::ref_sharing::PyLeaked |
|
|
15 | use crate::ref_sharing::PyLeaked; | |
|
16 | 16 | use hg::{utils::hg_path::HgPathBuf, CopyMapIter}; |
|
17 | 17 | |
|
18 | 18 | py_class!(pub class CopyMap |py| { |
@@ -104,14 +104,14 b' impl CopyMap {' | |||
|
104 | 104 | |
|
105 | 105 | py_shared_iterator!( |
|
106 | 106 | CopyMapKeysIterator, |
|
107 |
PyLeaked |
|
|
107 | PyLeaked<CopyMapIter<'static>>, | |
|
108 | 108 | CopyMap::translate_key, |
|
109 | 109 | Option<PyBytes> |
|
110 | 110 | ); |
|
111 | 111 | |
|
112 | 112 | py_shared_iterator!( |
|
113 | 113 | CopyMapItemsIterator, |
|
114 |
PyLeaked |
|
|
114 | PyLeaked<CopyMapIter<'static>>, | |
|
115 | 115 | CopyMap::translate_key_value, |
|
116 | 116 | Option<(PyBytes, PyBytes)> |
|
117 | 117 | ); |
@@ -17,7 +17,7 b' use cpython::{' | |||
|
17 | 17 | }; |
|
18 | 18 | |
|
19 | 19 | use crate::dirstate::extract_dirstate; |
|
20 |
use crate::ref_sharing::{PyLeaked |
|
|
20 | use crate::ref_sharing::{PyLeaked, PySharedRefCell}; | |
|
21 | 21 | use hg::{ |
|
22 | 22 | utils::hg_path::{HgPath, HgPathBuf}, |
|
23 | 23 | DirsMultiset, DirsMultisetIter, DirstateMapError, DirstateParseError, |
@@ -123,7 +123,7 b' impl Dirs {' | |||
|
123 | 123 | |
|
124 | 124 | py_shared_iterator!( |
|
125 | 125 | DirsMultisetKeysIterator, |
|
126 |
PyLeaked |
|
|
126 | PyLeaked<DirsMultisetIter<'static>>, | |
|
127 | 127 | Dirs::translate_key, |
|
128 | 128 | Option<PyBytes> |
|
129 | 129 | ); |
@@ -20,7 +20,7 b' use cpython::{' | |||
|
20 | 20 | use crate::{ |
|
21 | 21 | dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator}, |
|
22 | 22 | dirstate::{dirs_multiset::Dirs, make_dirstate_tuple}, |
|
23 |
ref_sharing::{PyLeaked |
|
|
23 | ref_sharing::{PyLeaked, PySharedRefCell}, | |
|
24 | 24 | }; |
|
25 | 25 | use hg::{ |
|
26 | 26 | utils::hg_path::{HgPath, HgPathBuf}, |
@@ -483,14 +483,14 b' py_shared_ref!(DirstateMap, RustDirstate' | |||
|
483 | 483 | |
|
484 | 484 | py_shared_iterator!( |
|
485 | 485 | DirstateMapKeysIterator, |
|
486 |
PyLeaked |
|
|
486 | PyLeaked<StateMapIter<'static>>, | |
|
487 | 487 | DirstateMap::translate_key, |
|
488 | 488 | Option<PyBytes> |
|
489 | 489 | ); |
|
490 | 490 | |
|
491 | 491 | py_shared_iterator!( |
|
492 | 492 | DirstateMapItemsIterator, |
|
493 |
PyLeaked |
|
|
493 | PyLeaked<StateMapIter<'static>>, | |
|
494 | 494 | DirstateMap::translate_key_value, |
|
495 | 495 | Option<(PyBytes, PyObject)> |
|
496 | 496 | ); |
@@ -186,12 +186,12 b" impl<'a, T> PySharedRef<'a, T> {" | |||
|
186 | 186 | } |
|
187 | 187 | |
|
188 | 188 | /// Returns a leaked reference. |
|
189 |
pub fn leak_immutable(&self) -> PyResult<PyLeaked |
|
|
189 | pub fn leak_immutable(&self) -> PyResult<PyLeaked<&'static T>> { | |
|
190 | 190 | let state = &self.data.py_shared_state; |
|
191 | 191 | unsafe { |
|
192 | 192 | let (static_ref, static_state_ref) = |
|
193 | 193 | state.leak_immutable(self.py, self.data)?; |
|
194 |
Ok(PyLeaked |
|
|
194 | Ok(PyLeaked::new( | |
|
195 | 195 | self.py, |
|
196 | 196 | self.owner, |
|
197 | 197 | static_ref, |
@@ -307,16 +307,16 b' macro_rules! py_shared_ref {' | |||
|
307 | 307 | } |
|
308 | 308 | |
|
309 | 309 | /// Manage immutable references to `PyObject` leaked into Python iterators. |
|
310 |
pub struct PyLeaked |
|
|
310 | pub struct PyLeaked<T> { | |
|
311 | 311 | inner: PyObject, |
|
312 | 312 | data: Option<T>, |
|
313 | 313 | py_shared_state: &'static PySharedState, |
|
314 | 314 | } |
|
315 | 315 | |
|
316 |
// DO NOT implement Deref for PyLeaked |
|
|
316 | // DO NOT implement Deref for PyLeaked<T>! Dereferencing PyLeaked | |
|
317 | 317 | // without taking Python GIL wouldn't be safe. |
|
318 | 318 | |
|
319 |
impl<T> PyLeaked |
|
|
319 | impl<T> PyLeaked<T> { | |
|
320 | 320 | /// # Safety |
|
321 | 321 | /// |
|
322 | 322 | /// The `py_shared_state` must be owned by the `inner` Python object. |
@@ -355,19 +355,19 b' impl<T> PyLeakedRef<T> {' | |||
|
355 | 355 | /// |
|
356 | 356 | /// The lifetime of the object passed in to the function `f` is cheated. |
|
357 | 357 | /// It's typically a static reference, but is valid only while the |
|
358 |
/// corresponding `PyLeaked |
|
|
358 | /// corresponding `PyLeaked` is alive. Do not copy it out of the | |
|
359 | 359 | /// function call. |
|
360 | 360 | pub unsafe fn map<U>( |
|
361 | 361 | mut self, |
|
362 | 362 | py: Python, |
|
363 | 363 | f: impl FnOnce(T) -> U, |
|
364 |
) -> PyLeaked |
|
|
364 | ) -> PyLeaked<U> { | |
|
365 | 365 | // f() could make the self.data outlive. That's why map() is unsafe. |
|
366 | 366 | // In order to make this function safe, maybe we'll need a way to |
|
367 | 367 | // temporarily restrict the lifetime of self.data and translate the |
|
368 | 368 | // returned object back to Something<'static>. |
|
369 | 369 | let new_data = f(self.data.take().unwrap()); |
|
370 |
PyLeaked |
|
|
370 | PyLeaked { | |
|
371 | 371 | inner: self.inner.clone_ref(py), |
|
372 | 372 | data: Some(new_data), |
|
373 | 373 | py_shared_state: self.py_shared_state, |
@@ -375,7 +375,7 b' impl<T> PyLeakedRef<T> {' | |||
|
375 | 375 | } |
|
376 | 376 | } |
|
377 | 377 | |
|
378 |
impl<T> Drop for PyLeaked |
|
|
378 | impl<T> Drop for PyLeaked<T> { | |
|
379 | 379 | fn drop(&mut self) { |
|
380 | 380 | // py_shared_state should be alive since we do have |
|
381 | 381 | // a Python reference to the owner object. Taking GIL makes |
@@ -383,7 +383,7 b' impl<T> Drop for PyLeakedRef<T> {' | |||
|
383 | 383 | let gil = Python::acquire_gil(); |
|
384 | 384 | let py = gil.python(); |
|
385 | 385 | if self.data.is_none() { |
|
386 |
return; // moved to another PyLeaked |
|
|
386 | return; // moved to another PyLeaked | |
|
387 | 387 | } |
|
388 | 388 | self.py_shared_state.decrease_leak_count(py, false); |
|
389 | 389 | } |
@@ -439,7 +439,7 b' impl<T> Drop for PyLeakedRef<T> {' | |||
|
439 | 439 | /// |
|
440 | 440 | /// py_shared_iterator!( |
|
441 | 441 | /// MyTypeItemsIterator, |
|
442 |
/// PyLeaked |
|
|
442 | /// PyLeaked<HashMap<'static, Vec<u8>, Vec<u8>>>, | |
|
443 | 443 | /// MyType::translate_key_value, |
|
444 | 444 | /// Option<(PyBytes, PyBytes)> |
|
445 | 445 | /// ); |
General Comments 0
You need to be logged in to leave comments.
Login now