Mercurial > hg
comparison rust/hg-cpython/src/ref_sharing.rs @ 44205:f015d679f08c
rust-cpython: inline PySharedState::leak_immutable() and PyLeaked::new()
For the same reason as the previous patch. The unsafe stuff can be better
documented if these functions are inlined.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 19 Oct 2019 16:48:34 +0900 |
parents | bafdaf4858d8 |
children | 9804badd5970 |
comparison
equal
deleted
inserted
replaced
44204:bafdaf4858d8 | 44205:f015d679f08c |
---|---|
55 borrow_count: AtomicUsize, | 55 borrow_count: AtomicUsize, |
56 generation: AtomicUsize, | 56 generation: AtomicUsize, |
57 } | 57 } |
58 | 58 |
59 impl PySharedState { | 59 impl PySharedState { |
60 /// Return a reference to the wrapped data and its state with an | |
61 /// artificial static lifetime. | |
62 /// We need to be protected by the GIL for thread-safety. | |
63 /// | |
64 /// # Safety | |
65 /// | |
66 /// This is highly unsafe since the lifetime of the given data can be | |
67 /// extended. Do not call this function directly. | |
68 unsafe fn leak_immutable<T>( | |
69 &self, | |
70 _py: Python, | |
71 data: Ref<T>, | |
72 ) -> (&'static T, &'static PySharedState) { | |
73 let ptr: *const T = &*data; | |
74 let state_ptr: *const PySharedState = self; | |
75 (&*ptr, &*state_ptr) | |
76 } | |
77 | |
78 fn current_borrow_count(&self, _py: Python) -> usize { | 60 fn current_borrow_count(&self, _py: Python) -> usize { |
79 self.borrow_count.load(Ordering::Relaxed) | 61 self.borrow_count.load(Ordering::Relaxed) |
80 } | 62 } |
81 | 63 |
82 fn increase_borrow_count(&self, _py: Python) { | 64 fn increase_borrow_count(&self, _py: Python) { |
221 pub fn leak_immutable(&self) -> PyLeaked<&'static T> { | 203 pub fn leak_immutable(&self) -> PyLeaked<&'static T> { |
222 let state = &self.data.py_shared_state; | 204 let state = &self.data.py_shared_state; |
223 // make sure self.data isn't mutably borrowed; otherwise the | 205 // make sure self.data isn't mutably borrowed; otherwise the |
224 // generation number can't be trusted. | 206 // generation number can't be trusted. |
225 let data_ref = self.borrow(); | 207 let data_ref = self.borrow(); |
226 unsafe { | 208 |
227 let (static_ref, static_state_ref) = | 209 // &'static cast is safe because data_ptr and state_ptr are owned |
228 state.leak_immutable(self.py, data_ref); | 210 // by self.owner, and we do have the GIL for thread safety. |
229 PyLeaked::new(self.py, self.owner, static_ref, static_state_ref) | 211 let data_ptr: *const T = &*data_ref; |
212 let state_ptr: *const PySharedState = state; | |
213 PyLeaked::<&'static T> { | |
214 inner: self.owner.clone_ref(self.py), | |
215 data: unsafe { &*data_ptr }, | |
216 py_shared_state: unsafe { &*state_ptr }, | |
217 generation: state.current_generation(self.py), | |
230 } | 218 } |
231 } | 219 } |
232 } | 220 } |
233 | 221 |
234 /// Allows a `py_class!` generated struct to share references to one of its | 222 /// Allows a `py_class!` generated struct to share references to one of its |
302 // DO NOT implement Deref for PyLeaked<T>! Dereferencing PyLeaked | 290 // DO NOT implement Deref for PyLeaked<T>! Dereferencing PyLeaked |
303 // without taking Python GIL wouldn't be safe. Also, the underling reference | 291 // without taking Python GIL wouldn't be safe. Also, the underling reference |
304 // is invalid if generation != py_shared_state.generation. | 292 // is invalid if generation != py_shared_state.generation. |
305 | 293 |
306 impl<T> PyLeaked<T> { | 294 impl<T> PyLeaked<T> { |
307 /// # Safety | |
308 /// | |
309 /// The `py_shared_state` must be owned by the `inner` Python object. | |
310 fn new( | |
311 py: Python, | |
312 inner: &PyObject, | |
313 data: T, | |
314 py_shared_state: &'static PySharedState, | |
315 ) -> Self { | |
316 Self { | |
317 inner: inner.clone_ref(py), | |
318 data: data, | |
319 py_shared_state, | |
320 generation: py_shared_state.current_generation(py), | |
321 } | |
322 } | |
323 | |
324 /// Immutably borrows the wrapped value. | 295 /// Immutably borrows the wrapped value. |
325 /// | 296 /// |
326 /// Borrowing fails if the underlying reference has been invalidated. | 297 /// Borrowing fails if the underlying reference has been invalidated. |
327 pub fn try_borrow<'a>( | 298 pub fn try_borrow<'a>( |
328 &'a self, | 299 &'a self, |