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