117 |
117 |
118 /// run `try_borrow_mut` on the `string` field and assert it is not an error |
118 /// run `try_borrow_mut` on the `string` field and assert it is not an error |
119 /// |
119 /// |
120 /// Simply returning the `Result` is not possible, because that is |
120 /// Simply returning the `Result` is not possible, because that is |
121 /// returning a reference to data owned by the function |
121 /// returning a reference to data owned by the function |
122 fn assert_try_borrow_string_mut_ok(owner: &Bound<'_, Owner>) { |
122 fn assert_try_write_string_ok(owner: &Bound<'_, Owner>) { |
123 let cell = &owner.borrow().string; |
123 let cell = &owner.borrow().string; |
124 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
124 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
125 assert!(shared_ref.try_borrow_mut().is_ok()); |
125 assert!(shared_ref.try_write().is_ok()); |
126 } |
126 } |
127 |
127 |
128 fn assert_try_borrow_string_mut_err(owner: &Bound<'_, Owner>) { |
128 fn assert_try_write_string_err(owner: &Bound<'_, Owner>) { |
129 let cell = &owner.borrow().string; |
129 let cell = &owner.borrow().string; |
130 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
130 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
131 assert!(shared_ref.try_borrow_mut().is_err()); |
131 assert!(shared_ref.try_write().is_err()); |
132 } |
132 } |
133 |
133 |
134 fn assert_try_borrow_string_err(owner: &Bound<'_, Owner>) { |
134 fn assert_try_read_string_err(owner: &Bound<'_, Owner>) { |
135 let cell = &owner.borrow().string; |
135 let cell = &owner.borrow().string; |
136 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
136 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
137 assert!(shared_ref.try_borrow().is_err()); |
137 assert!(shared_ref.try_read().is_err()); |
138 } |
138 } |
139 |
139 |
140 #[test] |
140 #[test] |
141 fn test_try_borrow_mut_while_leaked_ref() -> PyResult<()> { |
141 fn test_try_write_while_leaked_ref() -> PyResult<()> { |
142 with_setup(|py, owner| { |
142 with_setup(|py, owner| { |
143 assert_try_borrow_string_mut_ok(owner); |
143 assert_try_write_string_ok(owner); |
144 let leaked = leak_string(owner); |
144 let leaked = leak_string(owner); |
145 { |
145 { |
146 let _leaked_ref = unsafe { leaked.try_borrow(py) }.unwrap(); |
146 let _leaked_ref = unsafe { leaked.try_borrow(py) }.unwrap(); |
147 assert_try_borrow_string_mut_err(owner); |
147 assert_try_write_string_err(owner); |
148 { |
148 { |
149 let _leaked_ref2 = unsafe { leaked.try_borrow(py) }.unwrap(); |
149 let _leaked_ref2 = unsafe { leaked.try_borrow(py) }.unwrap(); |
150 assert_try_borrow_string_mut_err(owner); |
150 assert_try_write_string_err(owner); |
151 } |
151 } |
152 assert_try_borrow_string_mut_err(owner); |
152 assert_try_write_string_err(owner); |
153 } |
153 } |
154 assert_try_borrow_string_mut_ok(owner); |
154 assert_try_write_string_ok(owner); |
155 Ok(()) |
155 Ok(()) |
156 }) |
156 }) |
157 } |
157 } |
158 |
158 |
159 #[test] |
159 #[test] |
160 fn test_try_borrow_mut_while_leaked_ref_mut() -> PyResult<()> { |
160 fn test_try_write_while_leaked_ref_mut() -> PyResult<()> { |
161 with_setup(|py, owner| { |
161 with_setup(|py, owner| { |
162 assert_try_borrow_string_mut_ok(owner); |
162 assert_try_write_string_ok(owner); |
163 let leaked = leak_string(owner); |
163 let leaked = leak_string(owner); |
164 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
164 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
165 { |
165 { |
166 let _leaked_ref = |
166 let _leaked_ref = |
167 unsafe { leaked_iter.try_borrow_mut(py) }.unwrap(); |
167 unsafe { leaked_iter.try_borrow_mut(py) }.unwrap(); |
168 assert_try_borrow_string_mut_err(owner); |
168 assert_try_write_string_err(owner); |
169 } |
169 } |
170 assert_try_borrow_string_mut_ok(owner); |
170 assert_try_write_string_ok(owner); |
171 Ok(()) |
171 Ok(()) |
172 }) |
172 }) |
173 } |
173 } |
174 |
174 |
175 #[test] |
175 #[test] |
176 fn test_try_leak_while_borrow_mut() -> PyResult<()> { |
176 fn test_try_leak_while_write() -> PyResult<()> { |
177 with_setup(|_py, owner| { |
177 with_setup(|_py, owner| { |
178 let cell = &owner.borrow().string; |
178 let cell = &owner.borrow().string; |
179 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
179 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
180 let _mut_ref = shared_ref.borrow_mut(); |
180 let _mut_ref = shared_ref.write(); |
181 |
181 |
182 assert!(try_leak_string(owner).is_err()); |
182 assert!(try_leak_string(owner).is_err()); |
183 Ok(()) |
183 Ok(()) |
184 }) |
184 }) |
185 } |
185 } |
186 |
186 |
187 #[test] |
187 #[test] |
188 #[should_panic(expected = "already mutably borrowed")] |
188 #[should_panic(expected = "already mutably borrowed")] |
189 fn test_leak_while_borrow_mut() { |
189 fn test_leak_while_write() { |
190 with_setup(|_py, owner| { |
190 with_setup(|_py, owner| { |
191 let cell = &owner.borrow().string; |
191 let cell = &owner.borrow().string; |
192 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
192 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
193 let _mut_ref = shared_ref.borrow_mut(); |
193 let _mut_ref = shared_ref.write(); |
194 |
194 |
195 leak_string(owner); |
195 leak_string(owner); |
196 Ok(()) |
196 Ok(()) |
197 }) |
197 }) |
198 .expect("should already have panicked") |
198 .expect("should already have panicked") |
199 } |
199 } |
200 |
200 |
201 #[test] |
201 #[test] |
202 fn test_try_borrow_mut_while_borrow() -> PyResult<()> { |
202 fn test_try_write_while_borrow() -> PyResult<()> { |
203 with_setup(|_py, owner| { |
203 with_setup(|_py, owner| { |
204 let cell = &owner.borrow().string; |
204 let cell = &owner.borrow().string; |
205 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
205 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
206 let _ref = shared_ref.borrow(); |
206 let _ref = shared_ref.read(); |
207 |
207 |
208 assert_try_borrow_string_mut_err(owner); |
208 assert_try_write_string_err(owner); |
209 Ok(()) |
209 Ok(()) |
210 }) |
210 }) |
211 } |
211 } |
212 |
212 |
213 #[test] |
213 #[test] |
214 #[should_panic(expected = "already borrowed")] |
214 #[should_panic(expected = "already borrowed")] |
215 fn test_borrow_mut_while_borrow() { |
215 fn test_write_while_borrow() { |
216 with_setup(|_py, owner| { |
216 with_setup(|_py, owner| { |
217 let cell = &owner.borrow().string; |
217 let cell = &owner.borrow().string; |
218 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
218 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
219 let _ref = shared_ref.borrow(); |
219 let _ref = shared_ref.read(); |
220 |
220 |
221 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; |
221 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; |
222 let _mut_ref = shared_ref2.borrow_mut(); |
222 let _mut_ref = shared_ref2.write(); |
223 Ok(()) |
223 Ok(()) |
224 }) |
224 }) |
225 .expect("should already have panicked") |
225 .expect("should already have panicked") |
226 } |
226 } |
227 |
227 |
228 #[test] |
228 #[test] |
229 fn test_try_borrow_while_borrow_mut() -> PyResult<()> { |
229 fn test_try_borrow_while_write() -> PyResult<()> { |
230 with_setup(|_py, owner| { |
230 with_setup(|_py, owner| { |
231 let cell = &owner.borrow().string; |
231 let cell = &owner.borrow().string; |
232 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
232 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
233 let _mut_ref = shared_ref.borrow_mut(); |
233 let _mut_ref = shared_ref.write(); |
234 |
234 |
235 assert_try_borrow_string_err(owner); |
235 assert_try_read_string_err(owner); |
236 Ok(()) |
236 Ok(()) |
237 }) |
237 }) |
238 } |
238 } |
239 |
239 |
240 #[test] |
240 #[test] |
241 #[should_panic(expected = "already mutably borrowed")] |
241 #[should_panic(expected = "already mutably borrowed")] |
242 fn test_borrow_while_borrow_mut() { |
242 fn test_borrow_while_write() { |
243 with_setup(|_py, owner| { |
243 with_setup(|_py, owner| { |
244 let cell = &owner.borrow().string; |
244 let cell = &owner.borrow().string; |
245 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
245 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; |
246 let _mut_ref = shared_ref.borrow_mut(); |
246 let _mut_ref = shared_ref.write(); |
247 |
247 |
248 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; |
248 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; |
249 let _ref = shared_ref2.borrow(); |
249 let _ref = shared_ref2.read(); |
250 Ok(()) |
250 Ok(()) |
251 }) |
251 }) |
252 .expect("should already have panicked") |
252 .expect("should already have panicked") |
253 } |
253 } |