Show More
@@ -13,6 +13,7 b' use std::cell::RefCell;' | |||||
13 |
|
13 | |||
14 | use crate::dirstate::dirstate_map::DirstateMap; |
|
14 | use crate::dirstate::dirstate_map::DirstateMap; | |
15 | use crate::ref_sharing::PyLeakedRef; |
|
15 | use crate::ref_sharing::PyLeakedRef; | |
|
16 | use hg::DirstateMap as RustDirstateMap; | |||
16 | use hg::{utils::hg_path::HgPathBuf, CopyMapIter}; |
|
17 | use hg::{utils::hg_path::HgPathBuf, CopyMapIter}; | |
17 |
|
18 | |||
18 | py_class!(pub class CopyMap |py| { |
|
19 | py_class!(pub class CopyMap |py| { | |
@@ -104,7 +105,7 b' impl CopyMap {' | |||||
104 |
|
105 | |||
105 | py_shared_iterator!( |
|
106 | py_shared_iterator!( | |
106 | CopyMapKeysIterator, |
|
107 | CopyMapKeysIterator, | |
107 | PyLeakedRef, |
|
108 | PyLeakedRef<&'static RustDirstateMap>, | |
108 | CopyMapIter<'static>, |
|
109 | CopyMapIter<'static>, | |
109 | CopyMap::translate_key, |
|
110 | CopyMap::translate_key, | |
110 | Option<PyBytes> |
|
111 | Option<PyBytes> | |
@@ -112,7 +113,7 b' py_shared_iterator!(' | |||||
112 |
|
113 | |||
113 | py_shared_iterator!( |
|
114 | py_shared_iterator!( | |
114 | CopyMapItemsIterator, |
|
115 | CopyMapItemsIterator, | |
115 | PyLeakedRef, |
|
116 | PyLeakedRef<&'static RustDirstateMap>, | |
116 | CopyMapIter<'static>, |
|
117 | CopyMapIter<'static>, | |
117 | CopyMap::translate_key_value, |
|
118 | CopyMap::translate_key_value, | |
118 | Option<(PyBytes, PyBytes)> |
|
119 | Option<(PyBytes, PyBytes)> |
@@ -92,8 +92,9 b' py_class!(pub class Dirs |py| {' | |||||
92 | }) |
|
92 | }) | |
93 | } |
|
93 | } | |
94 | def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> { |
|
94 | def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> { | |
95 |
let |
|
95 | let mut leak_handle = | |
96 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
96 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
97 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
97 | DirsMultisetKeysIterator::from_inner( |
|
98 | DirsMultisetKeysIterator::from_inner( | |
98 | py, |
|
99 | py, | |
99 | leak_handle, |
|
100 | leak_handle, | |
@@ -125,7 +126,7 b' impl Dirs {' | |||||
125 |
|
126 | |||
126 | py_shared_iterator!( |
|
127 | py_shared_iterator!( | |
127 | DirsMultisetKeysIterator, |
|
128 | DirsMultisetKeysIterator, | |
128 | PyLeakedRef, |
|
129 | PyLeakedRef<&'static DirsMultiset>, | |
129 | DirsMultisetIter<'static>, |
|
130 | DirsMultisetIter<'static>, | |
130 | Dirs::translate_key, |
|
131 | Dirs::translate_key, | |
131 | Option<PyBytes> |
|
132 | Option<PyBytes> |
@@ -304,8 +304,9 b' py_class!(pub class DirstateMap |py| {' | |||||
304 | } |
|
304 | } | |
305 |
|
305 | |||
306 | def keys(&self) -> PyResult<DirstateMapKeysIterator> { |
|
306 | def keys(&self) -> PyResult<DirstateMapKeysIterator> { | |
307 |
let |
|
307 | let mut leak_handle = | |
308 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
308 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
309 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
309 | DirstateMapKeysIterator::from_inner( |
|
310 | DirstateMapKeysIterator::from_inner( | |
310 | py, |
|
311 | py, | |
311 | leak_handle, |
|
312 | leak_handle, | |
@@ -314,8 +315,9 b' py_class!(pub class DirstateMap |py| {' | |||||
314 | } |
|
315 | } | |
315 |
|
316 | |||
316 | def items(&self) -> PyResult<DirstateMapItemsIterator> { |
|
317 | def items(&self) -> PyResult<DirstateMapItemsIterator> { | |
317 |
let |
|
318 | let mut leak_handle = | |
318 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
319 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
320 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
319 | DirstateMapItemsIterator::from_inner( |
|
321 | DirstateMapItemsIterator::from_inner( | |
320 | py, |
|
322 | py, | |
321 | leak_handle, |
|
323 | leak_handle, | |
@@ -324,8 +326,9 b' py_class!(pub class DirstateMap |py| {' | |||||
324 | } |
|
326 | } | |
325 |
|
327 | |||
326 | def __iter__(&self) -> PyResult<DirstateMapKeysIterator> { |
|
328 | def __iter__(&self) -> PyResult<DirstateMapKeysIterator> { | |
327 |
let |
|
329 | let mut leak_handle = | |
328 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
330 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
331 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
329 | DirstateMapKeysIterator::from_inner( |
|
332 | DirstateMapKeysIterator::from_inner( | |
330 | py, |
|
333 | py, | |
331 | leak_handle, |
|
334 | leak_handle, | |
@@ -443,8 +446,9 b' py_class!(pub class DirstateMap |py| {' | |||||
443 | } |
|
446 | } | |
444 |
|
447 | |||
445 | def copymapiter(&self) -> PyResult<CopyMapKeysIterator> { |
|
448 | def copymapiter(&self) -> PyResult<CopyMapKeysIterator> { | |
446 |
let |
|
449 | let mut leak_handle = | |
447 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
450 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
451 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
448 | CopyMapKeysIterator::from_inner( |
|
452 | CopyMapKeysIterator::from_inner( | |
449 | py, |
|
453 | py, | |
450 | leak_handle, |
|
454 | leak_handle, | |
@@ -453,8 +457,9 b' py_class!(pub class DirstateMap |py| {' | |||||
453 | } |
|
457 | } | |
454 |
|
458 | |||
455 | def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> { |
|
459 | def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> { | |
456 |
let |
|
460 | let mut leak_handle = | |
457 | unsafe { self.inner_shared(py).leak_immutable()? }; |
|
461 | unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
462 | let leaked_ref = leak_handle.data.take().unwrap(); | |||
458 | CopyMapItemsIterator::from_inner( |
|
463 | CopyMapItemsIterator::from_inner( | |
459 | py, |
|
464 | py, | |
460 | leak_handle, |
|
465 | leak_handle, | |
@@ -493,7 +498,7 b' py_shared_ref!(DirstateMap, RustDirstate' | |||||
493 |
|
498 | |||
494 | py_shared_iterator!( |
|
499 | py_shared_iterator!( | |
495 | DirstateMapKeysIterator, |
|
500 | DirstateMapKeysIterator, | |
496 | PyLeakedRef, |
|
501 | PyLeakedRef<&'static RustDirstateMap>, | |
497 | StateMapIter<'static>, |
|
502 | StateMapIter<'static>, | |
498 | DirstateMap::translate_key, |
|
503 | DirstateMap::translate_key, | |
499 | Option<PyBytes> |
|
504 | Option<PyBytes> | |
@@ -501,7 +506,7 b' py_shared_iterator!(' | |||||
501 |
|
506 | |||
502 | py_shared_iterator!( |
|
507 | py_shared_iterator!( | |
503 | DirstateMapItemsIterator, |
|
508 | DirstateMapItemsIterator, | |
504 | PyLeakedRef, |
|
509 | PyLeakedRef<&'static RustDirstateMap>, | |
505 | StateMapIter<'static>, |
|
510 | StateMapIter<'static>, | |
506 | DirstateMap::translate_key_value, |
|
511 | DirstateMap::translate_key_value, | |
507 | Option<(PyBytes, PyObject)> |
|
512 | Option<(PyBytes, PyObject)> |
@@ -187,23 +187,24 b" impl<'a, T> PySharedRef<'a, T> {" | |||||
187 | self.data.borrow_mut(self.py) |
|
187 | self.data.borrow_mut(self.py) | |
188 | } |
|
188 | } | |
189 |
|
189 | |||
190 |
/// Returns a leaked reference |
|
190 | /// Returns a leaked reference temporarily held by its management object. | |
191 | /// |
|
191 | /// | |
192 | /// # Safety |
|
192 | /// # Safety | |
193 | /// |
|
193 | /// | |
194 | /// It's up to you to make sure that the management object lives |
|
194 | /// It's up to you to make sure that the management object lives | |
195 | /// longer than the leaked reference. Otherwise, you'll get a |
|
195 | /// longer than the leaked reference. Otherwise, you'll get a | |
196 | /// dangling reference. |
|
196 | /// dangling reference. | |
197 | pub unsafe fn leak_immutable( |
|
197 | pub unsafe fn leak_immutable(&self) -> PyResult<PyLeakedRef<&'static T>> { | |
198 | &self, |
|
|||
199 | ) -> PyResult<(PyLeakedRef, &'static T)> { |
|
|||
200 | let (static_ref, static_state_ref) = self |
|
198 | let (static_ref, static_state_ref) = self | |
201 | .data |
|
199 | .data | |
202 | .py_shared_state |
|
200 | .py_shared_state | |
203 | .leak_immutable(self.py, self.data)?; |
|
201 | .leak_immutable(self.py, self.data)?; | |
204 | let leak_handle = |
|
202 | Ok(PyLeakedRef::new( | |
205 | PyLeakedRef::new(self.py, self.owner, static_state_ref); |
|
203 | self.py, | |
206 | Ok((leak_handle, static_ref)) |
|
204 | self.owner, | |
|
205 | static_ref, | |||
|
206 | static_state_ref, | |||
|
207 | )) | |||
207 | } |
|
208 | } | |
208 | } |
|
209 | } | |
209 |
|
210 | |||
@@ -318,12 +319,13 b' macro_rules! py_shared_ref {' | |||||
318 | /// |
|
319 | /// | |
319 | /// In truth, this does not represent leaked references themselves; |
|
320 | /// In truth, this does not represent leaked references themselves; | |
320 | /// it is instead useful alongside them to manage them. |
|
321 | /// it is instead useful alongside them to manage them. | |
321 | pub struct PyLeakedRef { |
|
322 | pub struct PyLeakedRef<T> { | |
322 | _inner: PyObject, |
|
323 | _inner: PyObject, | |
|
324 | pub data: Option<T>, // TODO: remove pub | |||
323 | py_shared_state: &'static PySharedState, |
|
325 | py_shared_state: &'static PySharedState, | |
324 | } |
|
326 | } | |
325 |
|
327 | |||
326 | impl PyLeakedRef { |
|
328 | impl<T> PyLeakedRef<T> { | |
327 | /// # Safety |
|
329 | /// # Safety | |
328 | /// |
|
330 | /// | |
329 | /// The `py_shared_state` must be owned by the `inner` Python object. |
|
331 | /// The `py_shared_state` must be owned by the `inner` Python object. | |
@@ -332,16 +334,18 b' impl PyLeakedRef {' | |||||
332 | pub unsafe fn new( |
|
334 | pub unsafe fn new( | |
333 | py: Python, |
|
335 | py: Python, | |
334 | inner: &PyObject, |
|
336 | inner: &PyObject, | |
|
337 | data: T, | |||
335 | py_shared_state: &'static PySharedState, |
|
338 | py_shared_state: &'static PySharedState, | |
336 | ) -> Self { |
|
339 | ) -> Self { | |
337 | Self { |
|
340 | Self { | |
338 | _inner: inner.clone_ref(py), |
|
341 | _inner: inner.clone_ref(py), | |
|
342 | data: Some(data), | |||
339 | py_shared_state, |
|
343 | py_shared_state, | |
340 | } |
|
344 | } | |
341 | } |
|
345 | } | |
342 | } |
|
346 | } | |
343 |
|
347 | |||
344 | impl Drop for PyLeakedRef { |
|
348 | impl<T> Drop for PyLeakedRef<T> { | |
345 | fn drop(&mut self) { |
|
349 | fn drop(&mut self) { | |
346 | // py_shared_state should be alive since we do have |
|
350 | // py_shared_state should be alive since we do have | |
347 | // a Python reference to the owner object. Taking GIL makes |
|
351 | // a Python reference to the owner object. Taking GIL makes | |
@@ -379,8 +383,9 b' impl Drop for PyLeakedRef {' | |||||
379 | /// data inner: PySharedRefCell<MyStruct>; |
|
383 | /// data inner: PySharedRefCell<MyStruct>; | |
380 | /// |
|
384 | /// | |
381 | /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
|
385 | /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { | |
382 |
/// let |
|
386 | /// let mut leak_handle = | |
383 | /// unsafe { self.inner_shared(py).leak_immutable()? }; |
|
387 | /// unsafe { self.inner_shared(py).leak_immutable()? }; | |
|
388 | /// let leaked_ref = leak_handle.data.take().unwrap(); | |||
384 | /// MyTypeItemsIterator::from_inner( |
|
389 | /// MyTypeItemsIterator::from_inner( | |
385 | /// py, |
|
390 | /// py, | |
386 | /// leak_handle, |
|
391 | /// leak_handle, | |
@@ -406,7 +411,7 b' impl Drop for PyLeakedRef {' | |||||
406 | /// |
|
411 | /// | |
407 | /// py_shared_iterator!( |
|
412 | /// py_shared_iterator!( | |
408 | /// MyTypeItemsIterator, |
|
413 | /// MyTypeItemsIterator, | |
409 | /// PyLeakedRef, |
|
414 | /// PyLeakedRef<&'static MyStruct>, | |
410 | /// HashMap<'static, Vec<u8>, Vec<u8>>, |
|
415 | /// HashMap<'static, Vec<u8>, Vec<u8>>, | |
411 | /// MyType::translate_key_value, |
|
416 | /// MyType::translate_key_value, | |
412 | /// Option<(PyBytes, PyBytes)> |
|
417 | /// Option<(PyBytes, PyBytes)> |
General Comments 0
You need to be logged in to leave comments.
Login now