##// END OF EJS Templates
rust-cpython: make sure PySharedRef::borrow_mut() never panics...
Yuya Nishihara -
r44650:4a4c3b9f default
parent child Browse files
Show More
@@ -57,7 +57,7 b' struct PySharedState {'
57 }
57 }
58
58
59 impl PySharedState {
59 impl PySharedState {
60 fn borrow_mut<'a, T>(
60 fn try_borrow_mut<'a, T>(
61 &'a self,
61 &'a self,
62 py: Python<'a>,
62 py: Python<'a>,
63 pyrefmut: RefMut<'a, T>,
63 pyrefmut: RefMut<'a, T>,
@@ -162,16 +162,19 b' impl<T> PySharedRefCell<T> {'
162 fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> {
162 fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> {
163 // py_shared_state isn't involved since
163 // py_shared_state isn't involved since
164 // - inner.borrow() would fail if self is mutably borrowed,
164 // - inner.borrow() would fail if self is mutably borrowed,
165 // - and inner.borrow_mut() would fail while self is borrowed.
165 // - and inner.try_borrow_mut() would fail while self is borrowed.
166 self.inner.borrow()
166 self.inner.borrow()
167 }
167 }
168
168
169 // TODO: maybe this should be named as try_borrow_mut(), and use
169 fn try_borrow_mut<'a>(
170 // inner.try_borrow_mut(). The current implementation panics if
170 &'a self,
171 // self.inner has been borrowed, but returns error if py_shared_state
171 py: Python<'a>,
172 // refuses to borrow.
172 ) -> PyResult<RefMut<'a, T>> {
173 fn borrow_mut<'a>(&'a self, py: Python<'a>) -> PyResult<RefMut<'a, T>> {
173 let inner_ref = self
174 self.py_shared_state.borrow_mut(py, self.inner.borrow_mut())
174 .inner
175 .try_borrow_mut()
176 .map_err(|e| AlreadyBorrowed::new(py, e.to_string()))?;
177 self.py_shared_state.try_borrow_mut(py, inner_ref)
175 }
178 }
176 }
179 }
177
180
@@ -200,7 +203,7 b" impl<'a, T> PySharedRef<'a, T> {"
200 }
203 }
201
204
202 pub fn borrow_mut(&self) -> PyResult<RefMut<'a, T>> {
205 pub fn borrow_mut(&self) -> PyResult<RefMut<'a, T>> {
203 self.data.borrow_mut(self.py)
206 self.data.try_borrow_mut(self.py)
204 }
207 }
205
208
206 /// Returns a leaked reference.
209 /// Returns a leaked reference.
@@ -633,4 +636,12 b' mod test {'
633 let _mut_ref = owner.string_shared(py).borrow_mut();
636 let _mut_ref = owner.string_shared(py).borrow_mut();
634 owner.string_shared(py).leak_immutable();
637 owner.string_shared(py).leak_immutable();
635 }
638 }
639
640 #[test]
641 fn test_borrow_mut_while_borrow() {
642 let (gil, owner) = prepare_env();
643 let py = gil.python();
644 let _ref = owner.string_shared(py).borrow();
645 assert!(owner.string_shared(py).borrow_mut().is_err());
646 }
636 }
647 }
General Comments 0
You need to be logged in to leave comments. Login now