rust/hg-cpython/src/ref_sharing.rs
changeset 44203 2a24ead003f0
parent 44189 4a4c3b9fd91b
child 44204 bafdaf4858d8
equal deleted inserted replaced
44202:a7f8160cc4e4 44203:2a24ead003f0
   200 
   200 
   201     pub fn borrow(&self) -> Ref<'a, T> {
   201     pub fn borrow(&self) -> Ref<'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 
   209     /// Returns a leaked reference.
   221     /// Returns a leaked reference.
   210     ///
   222     ///
   570     #[test]
   582     #[test]
   571     fn test_leaked_borrow_after_mut() {
   583     fn test_leaked_borrow_after_mut() {
   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().unwrap().clear();
   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 
   579     #[test]
   591     #[test]
   580     fn test_leaked_borrow_mut_after_mut() {
   592     fn test_leaked_borrow_mut_after_mut() {
   581         let (gil, owner) = prepare_env();
   593         let (gil, owner) = prepare_env();
   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().unwrap().clear();
   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 
   589     #[test]
   601     #[test]
   590     #[should_panic(expected = "map() over invalidated leaked reference")]
   602     #[should_panic(expected = "map() over invalidated leaked reference")]
   591     fn test_leaked_map_after_mut() {
   603     fn test_leaked_map_after_mut() {
   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().unwrap().clear();
   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]
   632     #[should_panic(expected = "mutably borrowed")]
   644     #[should_panic(expected = "mutably borrowed")]
   633     fn test_leak_while_borrow_mut() {
   645     fn test_leak_while_borrow_mut() {
   636         let _mut_ref = owner.string_shared(py).borrow_mut();
   648         let _mut_ref = owner.string_shared(py).borrow_mut();
   637         owner.string_shared(py).leak_immutable();
   649         owner.string_shared(py).leak_immutable();
   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         assert!(owner.string_shared(py).borrow_mut().is_err());
   666         owner.string_shared(py).borrow_mut();
   646     }
   667     }
   647 }
   668 }