Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-cpython/src/ref_sharing.rs @ 43286:f8c114f20d2d
rust-cpython: require GIL to borrow immutable reference from PySharedRefCell
Since the inner value may be leaked, we probably need GIL to guarantee that
there's no data race.
inner(py).borrow() is replaced with inner_shared(py).borrow(), which basically
means any PySharedRefCell data should be accessed through PySharedRef wrapper.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 21 Sep 2019 17:15:50 +0900 |
parents | ffc1fbd7d1f5 |
children | 0df8312463ae |
rev | line source |
---|---|
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
1 // ref_sharing.rs |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 // |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
4 // |
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
5 // Permission is hereby granted, free of charge, to any person obtaining a copy |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
6 // of this software and associated documentation files (the "Software"), to |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
7 // deal in the Software without restriction, including without limitation the |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
9 // sell copies of the Software, and to permit persons to whom the Software is |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
10 // furnished to do so, subject to the following conditions: |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
11 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
12 // The above copyright notice and this permission notice shall be included in |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
13 // all copies or substantial portions of the Software. |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
14 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42943
diff
changeset
|
21 // IN THE SOFTWARE. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
23 //! Macros for use in the `hg-cpython` bridge library. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
24 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
25 use crate::exceptions::AlreadyBorrowed; |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
26 use cpython::{PyClone, PyObject, PyResult, Python}; |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
27 use std::cell::{Cell, Ref, RefCell, RefMut}; |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
28 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
29 /// Manages the shared state between Python and Rust |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
30 #[derive(Debug, Default)] |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 pub struct PySharedState { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
32 leak_count: Cell<usize>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
33 mutably_borrowed: Cell<bool>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
34 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
35 |
43175
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
36 // &PySharedState can be Send because any access to inner cells is |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
37 // synchronized by the GIL. |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
38 unsafe impl Sync for PySharedState {} |
a1908eb08342
rust-cpython: mark PySharedState as Sync so &'PySharedState can be Send
Yuya Nishihara <yuya@tcha.org>
parents:
43174
diff
changeset
|
39 |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
40 impl PySharedState { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
41 pub fn borrow_mut<'a, T>( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
42 &'a self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
43 py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
44 pyrefmut: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
45 ) -> PyResult<PyRefMut<'a, T>> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
46 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
47 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
48 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
49 "Cannot borrow mutably while there exists another \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
50 mutable reference in a Python object", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
51 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
52 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
53 match self.leak_count.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
54 0 => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
55 self.mutably_borrowed.replace(true); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
56 Ok(PyRefMut::new(py, pyrefmut, self)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
57 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
58 // TODO |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
59 // For now, this works differently than Python references |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
60 // in the case of iterators. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
61 // Python does not complain when the data an iterator |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
62 // points to is modified if the iterator is never used |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
63 // afterwards. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
64 // Here, we are stricter than this by refusing to give a |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
65 // mutable reference if it is already borrowed. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
66 // While the additional safety might be argued for, it |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
67 // breaks valid programming patterns in Python and we need |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
68 // to fix this issue down the line. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
69 _ => Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
70 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
71 "Cannot borrow mutably while there are \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
72 immutable references in Python objects", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
73 )), |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
74 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
75 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
76 |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
77 /// Return a reference to the wrapped data and its state with an |
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
78 /// artificial static lifetime. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
79 /// We need to be protected by the GIL for thread-safety. |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
80 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
81 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
82 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
83 /// This is highly unsafe since the lifetime of the given data can be |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
84 /// extended. Do not call this function directly. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
85 pub unsafe fn leak_immutable<T>( |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
86 &self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
87 py: Python, |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
88 data: &PySharedRefCell<T>, |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
89 ) -> PyResult<(&'static T, &'static PySharedState)> { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
90 if self.mutably_borrowed.get() { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
91 return Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
92 py, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
93 "Cannot borrow immutably while there is a \ |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
94 mutable reference in Python objects", |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
95 )); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
96 } |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
97 // TODO: it's weird that self is data.py_shared_state. Maybe we |
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
98 // can move stuff to PySharedRefCell? |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
99 let ptr = data.as_ptr(); |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
100 let state_ptr: *const PySharedState = &data.py_shared_state; |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
101 self.leak_count.replace(self.leak_count.get() + 1); |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
102 Ok((&*ptr, &*state_ptr)) |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
103 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
104 |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
105 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
106 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
107 /// It's unsafe to update the reference count without knowing the |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
108 /// reference is deleted. Do not call this function directly. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
109 pub unsafe fn decrease_leak_count(&self, _py: Python, mutable: bool) { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
110 if mutable { |
42943
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
111 assert_eq!(self.leak_count.get(), 0); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
112 assert!(self.mutably_borrowed.get()); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
113 self.mutably_borrowed.replace(false); |
42943
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
114 } else { |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
115 let count = self.leak_count.get(); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
116 assert!(count > 0); |
06080afd0565
rust-cpython: add sanity check to PySharedState::decrease_leak_count()
Yuya Nishihara <yuya@tcha.org>
parents:
42897
diff
changeset
|
117 self.leak_count.replace(count - 1); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
118 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
119 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
120 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
121 |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
122 /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
123 /// |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
124 /// Only immutable operation is allowed through this interface. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
125 #[derive(Debug)] |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
126 pub struct PySharedRefCell<T> { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
127 inner: RefCell<T>, |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
128 py_shared_state: PySharedState, |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
129 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
130 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
131 impl<T> PySharedRefCell<T> { |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
132 pub fn new(value: T) -> PySharedRefCell<T> { |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
133 Self { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
134 inner: RefCell::new(value), |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
135 py_shared_state: PySharedState::default(), |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
136 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
137 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
138 |
43286
f8c114f20d2d
rust-cpython: require GIL to borrow immutable reference from PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43285
diff
changeset
|
139 pub fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> { |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
140 // py_shared_state isn't involved since |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
141 // - inner.borrow() would fail if self is mutably borrowed, |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
142 // - and inner.borrow_mut() would fail while self is borrowed. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
143 self.inner.borrow() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
144 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
145 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
146 pub fn as_ptr(&self) -> *mut T { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
147 self.inner.as_ptr() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
148 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
149 |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
150 // TODO: maybe this should be named as try_borrow_mut(), and use |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
151 // inner.try_borrow_mut(). The current implementation panics if |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
152 // self.inner has been borrowed, but returns error if py_shared_state |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
153 // refuses to borrow. |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
154 pub fn borrow_mut<'a>( |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
155 &'a self, |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
156 py: Python<'a>, |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
157 ) -> PyResult<PyRefMut<'a, T>> { |
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
158 self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
159 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
160 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
161 |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
162 /// Sharable data member of type `T` borrowed from the `PyObject`. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
163 pub struct PySharedRef<'a, T> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
164 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
165 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
166 data: &'a PySharedRefCell<T>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
167 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
168 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
169 impl<'a, T> PySharedRef<'a, T> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
170 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
171 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
172 /// The `data` must be owned by the `owner`. Otherwise, the leak count |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
173 /// would get wrong. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
174 pub unsafe fn new( |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
175 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
176 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
177 data: &'a PySharedRefCell<T>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
178 ) -> Self { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
179 Self { py, owner, data } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
180 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
181 |
43272
00222775d59b
rust-refsharing: add missing lifetime parameter in ref_sharing
Rapha?l Gom?s <rgomes@octobus.net>
parents:
43180
diff
changeset
|
182 pub fn borrow(&self) -> Ref<'a, T> { |
43286
f8c114f20d2d
rust-cpython: require GIL to borrow immutable reference from PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43285
diff
changeset
|
183 self.data.borrow(self.py) |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
184 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
185 |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
186 pub fn borrow_mut(&self) -> PyResult<PyRefMut<'a, T>> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
187 self.data.borrow_mut(self.py) |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
188 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
189 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
190 /// Returns a leaked reference. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
191 pub fn leak_immutable(&self) -> PyResult<PyLeakedRef<&'static T>> { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
192 let state = &self.data.py_shared_state; |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
193 unsafe { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
194 let (static_ref, static_state_ref) = |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
195 state.leak_immutable(self.py, self.data)?; |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
196 Ok(PyLeakedRef::new( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
197 self.py, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
198 self.owner, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
199 static_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
200 static_state_ref, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
201 )) |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
202 } |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
203 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
204 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
205 |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
206 /// Holds a mutable reference to data shared between Python and Rust. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
207 pub struct PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
208 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
209 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
210 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
211 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
212 impl<'a, T> PyRefMut<'a, T> { |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
213 // Must be constructed by PySharedState after checking its leak_count. |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
214 // Otherwise, drop() would incorrectly update the state. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
215 fn new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
216 _py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
217 inner: RefMut<'a, T>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
218 py_shared_state: &'a PySharedState, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
219 ) -> Self { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
220 Self { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
221 inner, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
222 py_shared_state, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
223 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
224 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
225 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
226 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
227 impl<'a, T> std::ops::Deref for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
228 type Target = RefMut<'a, T>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
229 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
230 fn deref(&self) -> &Self::Target { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
231 &self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
232 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
233 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
234 impl<'a, T> std::ops::DerefMut for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
235 fn deref_mut(&mut self) -> &mut Self::Target { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
236 &mut self.inner |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
237 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
238 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
239 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
240 impl<'a, T> Drop for PyRefMut<'a, T> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
241 fn drop(&mut self) { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
242 let gil = Python::acquire_gil(); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
243 let py = gil.python(); |
42857
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
244 unsafe { |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
245 self.py_shared_state.decrease_leak_count(py, true); |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42856
diff
changeset
|
246 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
247 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
248 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
249 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
250 /// Allows a `py_class!` generated struct to share references to one of its |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
251 /// data members with Python. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
252 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
253 /// # Warning |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
254 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
255 /// TODO allow Python container types: for now, integration with the garbage |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
256 /// collector does not extend to Rust structs holding references to Python |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
257 /// objects. Should the need surface, `__traverse__` and `__clear__` will |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
258 /// need to be written as per the `rust-cpython` docs on GC integration. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
259 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
260 /// # Parameters |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
261 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
262 /// * `$name` is the same identifier used in for `py_class!` macro call. |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
263 /// * `$inner_struct` is the identifier of the underlying Rust struct |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
264 /// * `$data_member` is the identifier of the data member of `$inner_struct` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
265 /// that will be shared. |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
266 /// * `$shared_accessor` is the function name to be generated, which allows |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
267 /// safe access to the data member. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
268 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
269 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
270 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
271 /// `$data_member` must persist while the `$name` object is alive. In other |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
272 /// words, it must be an accessor to a data field of the Python object. |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
273 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
274 /// # Example |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
275 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
276 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
277 /// struct MyStruct { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
278 /// inner: Vec<u32>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
279 /// } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
280 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
281 /// py_class!(pub class MyType |py| { |
42855
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42849
diff
changeset
|
282 /// data inner: PySharedRefCell<MyStruct>; |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
283 /// }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
284 /// |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
285 /// py_shared_ref!(MyType, MyStruct, inner, inner_shared); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
286 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
287 macro_rules! py_shared_ref { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
288 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
289 $name: ident, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
290 $inner_struct: ident, |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
291 $data_member: ident, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
292 $shared_accessor: ident |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
293 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
294 impl $name { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
295 /// Returns a safe reference to the shared `$data_member`. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
296 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
297 /// This function guarantees that `PySharedRef` is created with |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
298 /// the valid `self` and `self.$data_member(py)` pair. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
299 fn $shared_accessor<'a>( |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
300 &'a self, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
301 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
302 ) -> $crate::ref_sharing::PySharedRef<'a, $inner_struct> { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
303 use cpython::PythonObject; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
304 use $crate::ref_sharing::PySharedRef; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
305 let owner = self.as_object(); |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
306 let data = self.$data_member(py); |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
307 unsafe { PySharedRef::new(py, owner, data) } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
308 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
309 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
310 }; |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
311 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
312 |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
313 /// Manage immutable references to `PyObject` leaked into Python iterators. |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
314 pub struct PyLeakedRef<T> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
315 inner: PyObject, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
316 data: Option<T>, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
317 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
318 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
319 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
320 // DO NOT implement Deref for PyLeakedRef<T>! Dereferencing PyLeakedRef |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
321 // without taking Python GIL wouldn't be safe. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
322 |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
323 impl<T> PyLeakedRef<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
324 /// # Safety |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
325 /// |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
326 /// The `py_shared_state` must be owned by the `inner` Python object. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
327 // Marked as unsafe so client code wouldn't construct PyLeakedRef |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
328 // struct by mistake. Its drop() is unsafe. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
329 pub unsafe fn new( |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
330 py: Python, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
331 inner: &PyObject, |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
332 data: T, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
333 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
334 ) -> Self { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
335 Self { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
336 inner: inner.clone_ref(py), |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
337 data: Some(data), |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
338 py_shared_state, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
339 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
340 } |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
341 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
342 /// Returns an immutable reference to the inner value. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
343 pub fn get_ref<'a>(&'a self, _py: Python<'a>) -> &'a T { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
344 self.data.as_ref().unwrap() |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
345 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
346 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
347 /// Returns a mutable reference to the inner value. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
348 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
349 /// Typically `T` is an iterator. If `T` is an immutable reference, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
350 /// `get_mut()` is useless since the inner value can't be mutated. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
351 pub fn get_mut<'a>(&'a mut self, _py: Python<'a>) -> &'a mut T { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
352 self.data.as_mut().unwrap() |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
353 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
354 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
355 /// Converts the inner value by the given function. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
356 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
357 /// Typically `T` is a static reference to a container, and `U` is an |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
358 /// iterator of that container. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
359 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
360 /// # Safety |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
361 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
362 /// The lifetime of the object passed in to the function `f` is cheated. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
363 /// It's typically a static reference, but is valid only while the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
364 /// corresponding `PyLeakedRef` is alive. Do not copy it out of the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
365 /// function call. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
366 pub unsafe fn map<U>( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
367 mut self, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
368 py: Python, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
369 f: impl FnOnce(T) -> U, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
370 ) -> PyLeakedRef<U> { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
371 // f() could make the self.data outlive. That's why map() is unsafe. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
372 // In order to make this function safe, maybe we'll need a way to |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
373 // temporarily restrict the lifetime of self.data and translate the |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
374 // returned object back to Something<'static>. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
375 let new_data = f(self.data.take().unwrap()); |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
376 PyLeakedRef { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
377 inner: self.inner.clone_ref(py), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
378 data: Some(new_data), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
379 py_shared_state: self.py_shared_state, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
380 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
381 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
382 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
383 |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
384 impl<T> Drop for PyLeakedRef<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
385 fn drop(&mut self) { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
386 // py_shared_state should be alive since we do have |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
387 // a Python reference to the owner object. Taking GIL makes |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
388 // sure that the state is only accessed by this thread. |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
389 let gil = Python::acquire_gil(); |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
390 let py = gil.python(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
391 if self.data.is_none() { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
392 return; // moved to another PyLeakedRef |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
393 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
394 unsafe { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
395 self.py_shared_state.decrease_leak_count(py, false); |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
396 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
397 } |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
398 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
399 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
400 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
401 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
402 /// TODO: this is a bit awkward to use, and a better (more complicated) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
403 /// procedural macro would simplify the interface a lot. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
404 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
405 /// # Parameters |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
406 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
407 /// * `$name` is the identifier to give to the resulting Rust struct. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
408 /// * `$leaked` corresponds to `$leaked` in the matching `py_shared_ref!` call. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
409 /// * `$iterator_type` is the type of the Rust iterator. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
410 /// * `$success_func` is a function for processing the Rust `(key, value)` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
411 /// tuple on iteration success, turning it into something Python understands. |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
412 /// * `$success_func` is the return type of `$success_func` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
413 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
414 /// # Example |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
415 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
416 /// ``` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
417 /// struct MyStruct { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
418 /// inner: HashMap<Vec<u8>, Vec<u8>>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
419 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
420 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
421 /// py_class!(pub class MyType |py| { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
422 /// data inner: PySharedRefCell<MyStruct>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
423 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
424 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
425 /// let leaked_ref = self.inner_shared(py).leak_immutable()?; |
42897
5ccc08d02280
rust-cpython: leverage py_shared_iterator::from_inner() where appropriate
Yuya Nishihara <yuya@tcha.org>
parents:
42896
diff
changeset
|
426 /// MyTypeItemsIterator::from_inner( |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
427 /// py, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
428 /// unsafe { leaked_ref.map(py, |o| o.iter()) }, |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
429 /// ) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
430 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
431 /// }); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
432 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
433 /// impl MyType { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
434 /// fn translate_key_value( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
435 /// py: Python, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
436 /// res: (&Vec<u8>, &Vec<u8>), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
437 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
438 /// let (f, entry) = res; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
439 /// Ok(Some(( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
440 /// PyBytes::new(py, f), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
441 /// PyBytes::new(py, entry), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
442 /// ))) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
443 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
444 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
445 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
446 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
447 /// |
42895
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42894
diff
changeset
|
448 /// py_shared_iterator!( |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
449 /// MyTypeItemsIterator, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
450 /// PyLeakedRef<HashMap<'static, Vec<u8>, Vec<u8>>>, |
42894
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
451 /// MyType::translate_key_value, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
452 /// Option<(PyBytes, PyBytes)> |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
453 /// ); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42893
diff
changeset
|
454 /// ``` |
42895
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42894
diff
changeset
|
455 macro_rules! py_shared_iterator { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
456 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
457 $name: ident, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
458 $leaked: ty, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
459 $success_func: expr, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
460 $success_type: ty |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
461 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
462 py_class!(pub class $name |py| { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
463 data inner: RefCell<Option<$leaked>>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
464 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
465 def __next__(&self) -> PyResult<$success_type> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
466 let mut inner_opt = self.inner(py).borrow_mut(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
467 if let Some(leaked) = inner_opt.as_mut() { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
468 match leaked.get_mut(py).next() { |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
469 None => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
470 // replace Some(inner) by None, drop $leaked |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
471 inner_opt.take(); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
472 Ok(None) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
473 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
474 Some(res) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
475 $success_func(py, res) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
476 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
477 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
478 } else { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
479 Ok(None) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
480 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
481 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
482 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
483 def __iter__(&self) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
484 Ok(self.clone_ref(py)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
485 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
486 }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
487 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
488 impl $name { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
489 pub fn from_inner( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
490 py: Python, |
42896
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42895
diff
changeset
|
491 leaked: $leaked, |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
492 ) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
493 Self::create_instance( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
494 py, |
42896
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42895
diff
changeset
|
495 RefCell::new(Some(leaked)), |
42768
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
496 ) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
497 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
498 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
499 }; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
500 } |