Show More
@@ -72,7 +72,7 b' py_class!(pub class Dirs |py| {' | |||||
72 | } |
|
72 | } | |
73 |
|
73 | |||
74 | def addpath(&self, path: PyObject) -> PyResult<PyObject> { |
|
74 | def addpath(&self, path: PyObject) -> PyResult<PyObject> { | |
75 |
self.inner_shared(py).borrow_mut() |
|
75 | self.inner_shared(py).borrow_mut().add_path( | |
76 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), |
|
76 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), | |
77 | ).and(Ok(py.None())).or_else(|e| { |
|
77 | ).and(Ok(py.None())).or_else(|e| { | |
78 | match e { |
|
78 | match e { | |
@@ -90,7 +90,7 b' py_class!(pub class Dirs |py| {' | |||||
90 | } |
|
90 | } | |
91 |
|
91 | |||
92 | def delpath(&self, path: PyObject) -> PyResult<PyObject> { |
|
92 | def delpath(&self, path: PyObject) -> PyResult<PyObject> { | |
93 |
self.inner_shared(py).borrow_mut() |
|
93 | self.inner_shared(py).borrow_mut().delete_path( | |
94 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), |
|
94 | HgPath::new(path.extract::<PyBytes>(py)?.data(py)), | |
95 | ) |
|
95 | ) | |
96 | .and(Ok(py.None())) |
|
96 | .and(Ok(py.None())) |
@@ -53,7 +53,7 b' py_class!(pub class DirstateMap |py| {' | |||||
53 | } |
|
53 | } | |
54 |
|
54 | |||
55 | def clear(&self) -> PyResult<PyObject> { |
|
55 | def clear(&self) -> PyResult<PyObject> { | |
56 |
self.inner_shared(py).borrow_mut() |
|
56 | self.inner_shared(py).borrow_mut().clear(); | |
57 | Ok(py.None()) |
|
57 | Ok(py.None()) | |
58 | } |
|
58 | } | |
59 |
|
59 | |||
@@ -80,7 +80,7 b' py_class!(pub class DirstateMap |py| {' | |||||
80 | size: PyObject, |
|
80 | size: PyObject, | |
81 | mtime: PyObject |
|
81 | mtime: PyObject | |
82 | ) -> PyResult<PyObject> { |
|
82 | ) -> PyResult<PyObject> { | |
83 |
self.inner_shared(py).borrow_mut() |
|
83 | self.inner_shared(py).borrow_mut().add_file( | |
84 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), |
|
84 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), | |
85 | oldstate.extract::<PyBytes>(py)?.data(py)[0] |
|
85 | oldstate.extract::<PyBytes>(py)?.data(py)[0] | |
86 | .try_into() |
|
86 | .try_into() | |
@@ -108,7 +108,7 b' py_class!(pub class DirstateMap |py| {' | |||||
108 | oldstate: PyObject, |
|
108 | oldstate: PyObject, | |
109 | size: PyObject |
|
109 | size: PyObject | |
110 | ) -> PyResult<PyObject> { |
|
110 | ) -> PyResult<PyObject> { | |
111 |
self.inner_shared(py).borrow_mut() |
|
111 | self.inner_shared(py).borrow_mut() | |
112 | .remove_file( |
|
112 | .remove_file( | |
113 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), |
|
113 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), | |
114 | oldstate.extract::<PyBytes>(py)?.data(py)[0] |
|
114 | oldstate.extract::<PyBytes>(py)?.data(py)[0] | |
@@ -132,7 +132,7 b' py_class!(pub class DirstateMap |py| {' | |||||
132 | f: PyObject, |
|
132 | f: PyObject, | |
133 | oldstate: PyObject |
|
133 | oldstate: PyObject | |
134 | ) -> PyResult<PyBool> { |
|
134 | ) -> PyResult<PyBool> { | |
135 |
self.inner_shared(py).borrow_mut() |
|
135 | self.inner_shared(py).borrow_mut() | |
136 | .drop_file( |
|
136 | .drop_file( | |
137 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), |
|
137 | HgPath::new(f.extract::<PyBytes>(py)?.data(py)), | |
138 | oldstate.extract::<PyBytes>(py)?.data(py)[0] |
|
138 | oldstate.extract::<PyBytes>(py)?.data(py)[0] | |
@@ -163,7 +163,7 b' py_class!(pub class DirstateMap |py| {' | |||||
163 | )) |
|
163 | )) | |
164 | }) |
|
164 | }) | |
165 | .collect(); |
|
165 | .collect(); | |
166 |
self.inner_shared(py).borrow_mut() |
|
166 | self.inner_shared(py).borrow_mut() | |
167 | .clear_ambiguous_times(files?, now.extract(py)?); |
|
167 | .clear_ambiguous_times(files?, now.extract(py)?); | |
168 | Ok(py.None()) |
|
168 | Ok(py.None()) | |
169 | } |
|
169 | } | |
@@ -198,7 +198,7 b' py_class!(pub class DirstateMap |py| {' | |||||
198 |
|
198 | |||
199 | def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> { |
|
199 | def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> { | |
200 | let d = d.extract::<PyBytes>(py)?; |
|
200 | let d = d.extract::<PyBytes>(py)?; | |
201 |
Ok(self.inner_shared(py).borrow_mut() |
|
201 | Ok(self.inner_shared(py).borrow_mut() | |
202 | .has_tracked_dir(HgPath::new(d.data(py))) |
|
202 | .has_tracked_dir(HgPath::new(d.data(py))) | |
203 | .map_err(|e| { |
|
203 | .map_err(|e| { | |
204 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
204 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
@@ -208,7 +208,7 b' py_class!(pub class DirstateMap |py| {' | |||||
208 |
|
208 | |||
209 | def hasdir(&self, d: PyObject) -> PyResult<PyBool> { |
|
209 | def hasdir(&self, d: PyObject) -> PyResult<PyBool> { | |
210 | let d = d.extract::<PyBytes>(py)?; |
|
210 | let d = d.extract::<PyBytes>(py)?; | |
211 |
Ok(self.inner_shared(py).borrow_mut() |
|
211 | Ok(self.inner_shared(py).borrow_mut() | |
212 | .has_dir(HgPath::new(d.data(py))) |
|
212 | .has_dir(HgPath::new(d.data(py))) | |
213 | .map_err(|e| { |
|
213 | .map_err(|e| { | |
214 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
214 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
@@ -217,7 +217,7 b' py_class!(pub class DirstateMap |py| {' | |||||
217 | } |
|
217 | } | |
218 |
|
218 | |||
219 | def parents(&self, st: PyObject) -> PyResult<PyTuple> { |
|
219 | def parents(&self, st: PyObject) -> PyResult<PyTuple> { | |
220 |
self.inner_shared(py).borrow_mut() |
|
220 | self.inner_shared(py).borrow_mut() | |
221 | .parents(st.extract::<PyBytes>(py)?.data(py)) |
|
221 | .parents(st.extract::<PyBytes>(py)?.data(py)) | |
222 | .and_then(|d| { |
|
222 | .and_then(|d| { | |
223 | Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2)) |
|
223 | Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2)) | |
@@ -235,13 +235,13 b' py_class!(pub class DirstateMap |py| {' | |||||
235 | let p1 = extract_node_id(py, &p1)?; |
|
235 | let p1 = extract_node_id(py, &p1)?; | |
236 | let p2 = extract_node_id(py, &p2)?; |
|
236 | let p2 = extract_node_id(py, &p2)?; | |
237 |
|
237 | |||
238 |
self.inner_shared(py).borrow_mut() |
|
238 | self.inner_shared(py).borrow_mut() | |
239 | .set_parents(&DirstateParents { p1, p2 }); |
|
239 | .set_parents(&DirstateParents { p1, p2 }); | |
240 | Ok(py.None()) |
|
240 | Ok(py.None()) | |
241 | } |
|
241 | } | |
242 |
|
242 | |||
243 | def read(&self, st: PyObject) -> PyResult<Option<PyObject>> { |
|
243 | def read(&self, st: PyObject) -> PyResult<Option<PyObject>> { | |
244 |
match self.inner_shared(py).borrow_mut() |
|
244 | match self.inner_shared(py).borrow_mut() | |
245 | .read(st.extract::<PyBytes>(py)?.data(py)) |
|
245 | .read(st.extract::<PyBytes>(py)?.data(py)) | |
246 | { |
|
246 | { | |
247 | Ok(Some(parents)) => Ok(Some( |
|
247 | Ok(Some(parents)) => Ok(Some( | |
@@ -268,7 +268,7 b' py_class!(pub class DirstateMap |py| {' | |||||
268 | p2: extract_node_id(py, &p2)?, |
|
268 | p2: extract_node_id(py, &p2)?, | |
269 | }; |
|
269 | }; | |
270 |
|
270 | |||
271 |
match self.inner_shared(py).borrow_mut() |
|
271 | match self.inner_shared(py).borrow_mut().pack(parents, now) { | |
272 | Ok(packed) => Ok(PyBytes::new(py, &packed)), |
|
272 | Ok(packed) => Ok(PyBytes::new(py, &packed)), | |
273 | Err(_) => Err(PyErr::new::<exc::OSError, _>( |
|
273 | Err(_) => Err(PyErr::new::<exc::OSError, _>( | |
274 | py, |
|
274 | py, | |
@@ -280,7 +280,7 b' py_class!(pub class DirstateMap |py| {' | |||||
280 | def filefoldmapasdict(&self) -> PyResult<PyDict> { |
|
280 | def filefoldmapasdict(&self) -> PyResult<PyDict> { | |
281 | let dict = PyDict::new(py); |
|
281 | let dict = PyDict::new(py); | |
282 | for (key, value) in |
|
282 | for (key, value) in | |
283 |
self.inner_shared(py).borrow_mut() |
|
283 | self.inner_shared(py).borrow_mut().build_file_fold_map().iter() | |
284 | { |
|
284 | { | |
285 | dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?; |
|
285 | dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?; | |
286 | } |
|
286 | } | |
@@ -336,7 +336,7 b' py_class!(pub class DirstateMap |py| {' | |||||
336 |
|
336 | |||
337 | def getdirs(&self) -> PyResult<Dirs> { |
|
337 | def getdirs(&self) -> PyResult<Dirs> { | |
338 | // TODO don't copy, share the reference |
|
338 | // TODO don't copy, share the reference | |
339 |
self.inner_shared(py).borrow_mut() |
|
339 | self.inner_shared(py).borrow_mut().set_dirs() | |
340 | .map_err(|e| { |
|
340 | .map_err(|e| { | |
341 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
341 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
342 | })?; |
|
342 | })?; | |
@@ -353,7 +353,7 b' py_class!(pub class DirstateMap |py| {' | |||||
353 | } |
|
353 | } | |
354 | def getalldirs(&self) -> PyResult<Dirs> { |
|
354 | def getalldirs(&self) -> PyResult<Dirs> { | |
355 | // TODO don't copy, share the reference |
|
355 | // TODO don't copy, share the reference | |
356 |
self.inner_shared(py).borrow_mut() |
|
356 | self.inner_shared(py).borrow_mut().set_all_dirs() | |
357 | .map_err(|e| { |
|
357 | .map_err(|e| { | |
358 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) |
|
358 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
359 | })?; |
|
359 | })?; | |
@@ -431,7 +431,7 b' py_class!(pub class DirstateMap |py| {' | |||||
431 | ) -> PyResult<PyObject> { |
|
431 | ) -> PyResult<PyObject> { | |
432 | let key = key.extract::<PyBytes>(py)?; |
|
432 | let key = key.extract::<PyBytes>(py)?; | |
433 | let value = value.extract::<PyBytes>(py)?; |
|
433 | let value = value.extract::<PyBytes>(py)?; | |
434 |
self.inner_shared(py).borrow_mut() |
|
434 | self.inner_shared(py).borrow_mut().copy_map.insert( | |
435 | HgPathBuf::from_bytes(key.data(py)), |
|
435 | HgPathBuf::from_bytes(key.data(py)), | |
436 | HgPathBuf::from_bytes(value.data(py)), |
|
436 | HgPathBuf::from_bytes(value.data(py)), | |
437 | ); |
|
437 | ); | |
@@ -445,7 +445,7 b' py_class!(pub class DirstateMap |py| {' | |||||
445 | let key = key.extract::<PyBytes>(py)?; |
|
445 | let key = key.extract::<PyBytes>(py)?; | |
446 | match self |
|
446 | match self | |
447 | .inner_shared(py) |
|
447 | .inner_shared(py) | |
448 |
.borrow_mut() |
|
448 | .borrow_mut() | |
449 | .copy_map |
|
449 | .copy_map | |
450 | .remove(HgPath::new(key.data(py))) |
|
450 | .remove(HgPath::new(key.data(py))) | |
451 | { |
|
451 | { |
@@ -202,7 +202,19 b" impl<'a, T> PySharedRef<'a, T> {" | |||||
202 | self.data.borrow(self.py) |
|
202 | self.data.borrow(self.py) | |
203 | } |
|
203 | } | |
204 |
|
204 | |||
205 | pub fn borrow_mut(&self) -> PyResult<RefMut<'a, T>> { |
|
205 | /// Mutably borrows the wrapped value. | |
|
206 | /// | |||
|
207 | /// # Panics | |||
|
208 | /// | |||
|
209 | /// Panics if the value is currently borrowed through `PySharedRef` | |||
|
210 | /// or `PyLeaked`. | |||
|
211 | pub fn borrow_mut(&self) -> RefMut<'a, T> { | |||
|
212 | self.try_borrow_mut().expect("already borrowed") | |||
|
213 | } | |||
|
214 | ||||
|
215 | /// Mutably borrows the wrapped value, returning an error if the value | |||
|
216 | /// is currently borrowed. | |||
|
217 | pub fn try_borrow_mut(&self) -> PyResult<RefMut<'a, T>> { | |||
206 | self.data.try_borrow_mut(self.py) |
|
218 | self.data.try_borrow_mut(self.py) | |
207 | } |
|
219 | } | |
208 |
|
220 | |||
@@ -572,7 +584,7 b' mod test {' | |||||
572 | let (gil, owner) = prepare_env(); |
|
584 | let (gil, owner) = prepare_env(); | |
573 | let py = gil.python(); |
|
585 | let py = gil.python(); | |
574 | let leaked = owner.string_shared(py).leak_immutable(); |
|
586 | let leaked = owner.string_shared(py).leak_immutable(); | |
575 |
owner.string_shared(py).borrow_mut(). |
|
587 | owner.string_shared(py).borrow_mut().clear(); | |
576 | assert!(leaked.try_borrow(py).is_err()); |
|
588 | assert!(leaked.try_borrow(py).is_err()); | |
577 | } |
|
589 | } | |
578 |
|
590 | |||
@@ -582,7 +594,7 b' mod test {' | |||||
582 | let py = gil.python(); |
|
594 | let py = gil.python(); | |
583 | let leaked = owner.string_shared(py).leak_immutable(); |
|
595 | let leaked = owner.string_shared(py).leak_immutable(); | |
584 | let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
|
596 | let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; | |
585 |
owner.string_shared(py).borrow_mut(). |
|
597 | owner.string_shared(py).borrow_mut().clear(); | |
586 | assert!(leaked_iter.try_borrow_mut(py).is_err()); |
|
598 | assert!(leaked_iter.try_borrow_mut(py).is_err()); | |
587 | } |
|
599 | } | |
588 |
|
600 | |||
@@ -592,40 +604,40 b' mod test {' | |||||
592 | let (gil, owner) = prepare_env(); |
|
604 | let (gil, owner) = prepare_env(); | |
593 | let py = gil.python(); |
|
605 | let py = gil.python(); | |
594 | let leaked = owner.string_shared(py).leak_immutable(); |
|
606 | let leaked = owner.string_shared(py).leak_immutable(); | |
595 |
owner.string_shared(py).borrow_mut(). |
|
607 | owner.string_shared(py).borrow_mut().clear(); | |
596 | let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
|
608 | let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; | |
597 | } |
|
609 | } | |
598 |
|
610 | |||
599 | #[test] |
|
611 | #[test] | |
600 | fn test_borrow_mut_while_leaked_ref() { |
|
612 | fn test_try_borrow_mut_while_leaked_ref() { | |
601 | let (gil, owner) = prepare_env(); |
|
613 | let (gil, owner) = prepare_env(); | |
602 | let py = gil.python(); |
|
614 | let py = gil.python(); | |
603 | assert!(owner.string_shared(py).borrow_mut().is_ok()); |
|
615 | assert!(owner.string_shared(py).try_borrow_mut().is_ok()); | |
604 | let leaked = owner.string_shared(py).leak_immutable(); |
|
616 | let leaked = owner.string_shared(py).leak_immutable(); | |
605 | { |
|
617 | { | |
606 | let _leaked_ref = leaked.try_borrow(py).unwrap(); |
|
618 | let _leaked_ref = leaked.try_borrow(py).unwrap(); | |
607 | assert!(owner.string_shared(py).borrow_mut().is_err()); |
|
619 | assert!(owner.string_shared(py).try_borrow_mut().is_err()); | |
608 | { |
|
620 | { | |
609 | let _leaked_ref2 = leaked.try_borrow(py).unwrap(); |
|
621 | let _leaked_ref2 = leaked.try_borrow(py).unwrap(); | |
610 | assert!(owner.string_shared(py).borrow_mut().is_err()); |
|
622 | assert!(owner.string_shared(py).try_borrow_mut().is_err()); | |
611 | } |
|
623 | } | |
612 | assert!(owner.string_shared(py).borrow_mut().is_err()); |
|
624 | assert!(owner.string_shared(py).try_borrow_mut().is_err()); | |
613 | } |
|
625 | } | |
614 | assert!(owner.string_shared(py).borrow_mut().is_ok()); |
|
626 | assert!(owner.string_shared(py).try_borrow_mut().is_ok()); | |
615 | } |
|
627 | } | |
616 |
|
628 | |||
617 | #[test] |
|
629 | #[test] | |
618 | fn test_borrow_mut_while_leaked_ref_mut() { |
|
630 | fn test_try_borrow_mut_while_leaked_ref_mut() { | |
619 | let (gil, owner) = prepare_env(); |
|
631 | let (gil, owner) = prepare_env(); | |
620 | let py = gil.python(); |
|
632 | let py = gil.python(); | |
621 | assert!(owner.string_shared(py).borrow_mut().is_ok()); |
|
633 | assert!(owner.string_shared(py).try_borrow_mut().is_ok()); | |
622 | let leaked = owner.string_shared(py).leak_immutable(); |
|
634 | let leaked = owner.string_shared(py).leak_immutable(); | |
623 | let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
|
635 | let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; | |
624 | { |
|
636 | { | |
625 | let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); |
|
637 | let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); | |
626 | assert!(owner.string_shared(py).borrow_mut().is_err()); |
|
638 | assert!(owner.string_shared(py).try_borrow_mut().is_err()); | |
627 | } |
|
639 | } | |
628 | assert!(owner.string_shared(py).borrow_mut().is_ok()); |
|
640 | assert!(owner.string_shared(py).try_borrow_mut().is_ok()); | |
629 | } |
|
641 | } | |
630 |
|
642 | |||
631 | #[test] |
|
643 | #[test] | |
@@ -638,10 +650,19 b' mod test {' | |||||
638 | } |
|
650 | } | |
639 |
|
651 | |||
640 | #[test] |
|
652 | #[test] | |
|
653 | fn test_try_borrow_mut_while_borrow() { | |||
|
654 | let (gil, owner) = prepare_env(); | |||
|
655 | let py = gil.python(); | |||
|
656 | let _ref = owner.string_shared(py).borrow(); | |||
|
657 | assert!(owner.string_shared(py).try_borrow_mut().is_err()); | |||
|
658 | } | |||
|
659 | ||||
|
660 | #[test] | |||
|
661 | #[should_panic(expected = "already borrowed")] | |||
641 | fn test_borrow_mut_while_borrow() { |
|
662 | fn test_borrow_mut_while_borrow() { | |
642 | let (gil, owner) = prepare_env(); |
|
663 | let (gil, owner) = prepare_env(); | |
643 | let py = gil.python(); |
|
664 | let py = gil.python(); | |
644 | let _ref = owner.string_shared(py).borrow(); |
|
665 | let _ref = owner.string_shared(py).borrow(); | |
645 |
|
|
666 | owner.string_shared(py).borrow_mut(); | |
646 | } |
|
667 | } | |
647 | } |
|
668 | } |
General Comments 0
You need to be logged in to leave comments.
Login now