Mercurial > public > mercurial-scm > hg
annotate rust/hg-cpython/src/ref_sharing.rs @ 43961:b69d5f3a41d0
rust-index: add a struct wrapping the C index
Implementing the full index logic in one go is journey larger than we would
like.
To achieve a smoother transition, we start with a simple Rust wrapper that delegates
allwork to the current C implementation. Once we will have a fully working index
object in Rust, we can easily start using more and more Rust Code with it.
The object in this patch is functional and tested. However, multiple of the
currently existing rust (in the `hg-cpython` crate) requires a `Graph`. Right
now we build this `Graph` (as cindex::Index) using the C index passed as
a PyObject. They will have to be updated to be made compatible.
Differential Revision: https://phab.mercurial-scm.org/D7655
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Mon, 23 Dec 2019 10:02:50 -0800 |
parents | 8418b77132c1 |
children | 1f9e6fbdd3e6 |
rev | line source |
---|---|
43082
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
diff
changeset
|
1 // ref_sharing.rs |
42752
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:
42939
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:
42939
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:
42939
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:
42939
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:
42939
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:
42939
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:
42939
diff
changeset
|
11 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
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:
42939
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:
42939
diff
changeset
|
14 // |
fdfe5cfb3723
rust-cpython: change license of ref_sharing.rs to MIT
Yuya Nishihara <yuya@tcha.org>
parents:
42939
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:
42939
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:
42939
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:
42939
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:
42939
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:
42939
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:
42939
diff
changeset
|
21 // IN THE SOFTWARE. |
42752
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; |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
26 use cpython::{exc, PyClone, PyErr, PyObject, PyResult, Python}; |
43428
6c0e47874217
rust-cpython: drop manual management of mutably_borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43427
diff
changeset
|
27 use std::cell::{Ref, RefCell, RefMut}; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
28 use std::ops::{Deref, DerefMut}; |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
29 use std::sync::atomic::{AtomicUsize, Ordering}; |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
30 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 /// Manages the shared state between Python and Rust |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
32 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
33 /// `PySharedState` is owned by `PySharedRefCell`, and is shared across its |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
34 /// derived references. The consistency of these references are guaranteed |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
35 /// as follows: |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
36 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
37 /// - The immutability of `py_class!` object fields. Any mutation of |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
38 /// `PySharedRefCell` is allowed only through its `borrow_mut()`. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
39 /// - The `py: Python<'_>` token, which makes sure that any data access is |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
40 /// synchronized by the GIL. |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
41 /// - The underlying `RefCell`, which prevents `PySharedRefCell` data from |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
42 /// being directly borrowed or leaked while it is mutably borrowed. |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
43 /// - The `borrow_count`, which is the number of references borrowed from |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
44 /// `PyLeaked`. Just like `RefCell`, mutation is prohibited while `PyLeaked` |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
45 /// is borrowed. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
46 /// - The `generation` counter, which increments on `borrow_mut()`. `PyLeaked` |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
47 /// reference is valid only if the `current_generation()` equals to the |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
48 /// `generation` at the time of `leak_immutable()`. |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
49 #[derive(Debug, Default)] |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
50 struct PySharedState { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
51 // The counter variable could be Cell<usize> since any operation on |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
52 // PySharedState is synchronized by the GIL, but being "atomic" makes |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
53 // PySharedState inherently Sync. The ordering requirement doesn't |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
54 // matter thanks to the GIL. |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
55 borrow_count: AtomicUsize, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
56 generation: AtomicUsize, |
42752
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 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
59 impl PySharedState { |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
60 fn borrow_mut<'a, T>( |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
61 &'a self, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
62 py: Python<'a>, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
63 pyrefmut: RefMut<'a, T>, |
43429
75b4eb98ad97
rust-cpython: remove useless PyRefMut wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
43428
diff
changeset
|
64 ) -> PyResult<RefMut<'a, T>> { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
65 match self.current_borrow_count(py) { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
66 0 => { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
67 // Note that this wraps around to the same value if mutably |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
68 // borrowed more than usize::MAX times, which wouldn't happen |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
69 // in practice. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
70 self.generation.fetch_add(1, Ordering::Relaxed); |
43429
75b4eb98ad97
rust-cpython: remove useless PyRefMut wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
43428
diff
changeset
|
71 Ok(pyrefmut) |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
72 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
73 _ => Err(AlreadyBorrowed::new( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
74 py, |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
75 "Cannot borrow mutably while immutably borrowed", |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
76 )), |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
77 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
78 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
79 |
43176
aaec70a5f9a8
rust-cpython: store leaked reference to PySharedState in $leaked struct
Yuya Nishihara <yuya@tcha.org>
parents:
43175
diff
changeset
|
80 /// 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
|
81 /// artificial static lifetime. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
82 /// We need to be protected by the GIL for thread-safety. |
42851
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
83 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
84 /// # Safety |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
85 /// |
64e28b891796
rust-cpython: mark unsafe functions as such
Yuya Nishihara <yuya@tcha.org>
parents:
42850
diff
changeset
|
86 /// 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:
42850
diff
changeset
|
87 /// extended. Do not call this function directly. |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
88 unsafe fn leak_immutable<T>( |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
89 &self, |
43428
6c0e47874217
rust-cpython: drop manual management of mutably_borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43427
diff
changeset
|
90 _py: Python, |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
91 data: Ref<T>, |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
92 ) -> (&'static T, &'static PySharedState) { |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
93 let ptr: *const T = &*data; |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
94 let state_ptr: *const PySharedState = self; |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
95 (&*ptr, &*state_ptr) |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
96 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
97 |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
98 fn current_borrow_count(&self, _py: Python) -> usize { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
99 self.borrow_count.load(Ordering::Relaxed) |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
100 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
101 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
102 fn increase_borrow_count(&self, _py: Python) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
103 // Note that this wraps around if there are more than usize::MAX |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
104 // borrowed references, which shouldn't happen due to memory limit. |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
105 self.borrow_count.fetch_add(1, Ordering::Relaxed); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
106 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
107 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
108 fn decrease_borrow_count(&self, _py: Python) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
109 let prev_count = self.borrow_count.fetch_sub(1, Ordering::Relaxed); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
110 assert!(prev_count > 0); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
111 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
112 |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
113 fn current_generation(&self, _py: Python) -> usize { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
114 self.generation.load(Ordering::Relaxed) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
115 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
116 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
117 |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
118 /// Helper to keep the borrow count updated while the shared object is |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
119 /// immutably borrowed without using the `RefCell` interface. |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
120 struct BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
121 py: Python<'a>, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
122 py_shared_state: &'a PySharedState, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
123 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
124 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
125 impl<'a> BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
126 fn new( |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
127 py: Python<'a>, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
128 py_shared_state: &'a PySharedState, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
129 ) -> BorrowPyShared<'a> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
130 py_shared_state.increase_borrow_count(py); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
131 BorrowPyShared { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
132 py, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
133 py_shared_state, |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
134 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
135 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
136 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
137 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
138 impl Drop for BorrowPyShared<'_> { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
139 fn drop(&mut self) { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
140 self.py_shared_state.decrease_borrow_count(self.py); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
141 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
142 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
143 |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
144 /// `RefCell` wrapper to be safely used in conjunction with `PySharedState`. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
145 /// |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
146 /// This object can be stored in a `py_class!` object as a data field. Any |
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
147 /// operation is allowed through the `PySharedRef` interface. |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
148 #[derive(Debug)] |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
149 pub struct PySharedRefCell<T> { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
150 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
|
151 py_shared_state: PySharedState, |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
152 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
153 |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
154 impl<T> PySharedRefCell<T> { |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
155 pub fn new(value: T) -> PySharedRefCell<T> { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
156 Self { |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
157 inner: RefCell::new(value), |
43173
070a38737334
rust-cpython: move py_shared_state to PySharedRefCell object
Yuya Nishihara <yuya@tcha.org>
parents:
43082
diff
changeset
|
158 py_shared_state: PySharedState::default(), |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
159 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
160 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
161 |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
162 fn borrow<'a>(&'a self, _py: Python<'a>) -> Ref<'a, T> { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
163 // py_shared_state isn't involved since |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
164 // - inner.borrow() would fail if self is mutably borrowed, |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
165 // - and inner.borrow_mut() would fail while self is borrowed. |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
166 self.inner.borrow() |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
167 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
168 |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
169 // 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
|
170 // 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
|
171 // 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
|
172 // refuses to borrow. |
43429
75b4eb98ad97
rust-cpython: remove useless PyRefMut wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
43428
diff
changeset
|
173 fn borrow_mut<'a>(&'a self, py: Python<'a>) -> PyResult<RefMut<'a, T>> { |
43174
1c675c5fe5fe
rust-cpython: move borrow_mut() to PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents:
43173
diff
changeset
|
174 self.py_shared_state.borrow_mut(py, self.inner.borrow_mut()) |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
175 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
176 } |
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
177 |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
178 /// 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
|
179 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
|
180 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
181 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
182 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
|
183 } |
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 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
|
186 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
187 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
188 /// 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
|
189 /// would get wrong. |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
190 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
|
191 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
192 owner: &'a PyObject, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
193 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
|
194 ) -> Self { |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
195 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
|
196 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
197 |
43272
00222775d59b
rust-refsharing: add missing lifetime parameter in ref_sharing
Rapha?l Gom?s <rgomes@octobus.net>
parents:
43180
diff
changeset
|
198 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
|
199 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
|
200 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
201 |
43429
75b4eb98ad97
rust-cpython: remove useless PyRefMut wrapper
Yuya Nishihara <yuya@tcha.org>
parents:
43428
diff
changeset
|
202 pub fn borrow_mut(&self) -> PyResult<RefMut<'a, T>> { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
203 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
|
204 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
205 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
206 /// Returns a leaked reference. |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
207 /// |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
208 /// # Panics |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
209 /// |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
210 /// Panics if this is mutably borrowed. |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
211 pub fn leak_immutable(&self) -> PyLeaked<&'static T> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
212 let state = &self.data.py_shared_state; |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
213 // make sure self.data isn't mutably borrowed; otherwise the |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
214 // generation number can't be trusted. |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
215 let data_ref = self.borrow(); |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
216 unsafe { |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
217 let (static_ref, static_state_ref) = |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
218 state.leak_immutable(self.py, data_ref); |
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
219 PyLeaked::new(self.py, self.owner, static_ref, static_state_ref) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
220 } |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
221 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
222 } |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
223 |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
224 /// 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
|
225 /// data members with Python. |
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 /// # Parameters |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
228 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
229 /// * `$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
|
230 /// * `$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
|
231 /// * `$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
|
232 /// 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
|
233 /// * `$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
|
234 /// 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
|
235 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
236 /// # Safety |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
237 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
238 /// `$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
|
239 /// words, it must be an accessor to a data field of the Python object. |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
240 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
241 /// # Example |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
242 /// |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
243 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
244 /// struct MyStruct { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
245 /// inner: Vec<u32>; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
246 /// } |
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 /// py_class!(pub class MyType |py| { |
42849
8db8fa1de2ef
rust-cpython: introduce restricted variant of RefCell
Yuya Nishihara <yuya@tcha.org>
parents:
42839
diff
changeset
|
249 /// data inner: PySharedRefCell<MyStruct>; |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
250 /// }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
251 /// |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
252 /// py_shared_ref!(MyType, MyStruct, inner, inner_shared); |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
253 /// ``` |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
254 macro_rules! py_shared_ref { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
255 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
256 $name: ident, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
257 $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
|
258 $data_member: ident, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
259 $shared_accessor: ident |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
260 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
261 impl $name { |
43178
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
262 /// 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
|
263 /// |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
264 /// 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
|
265 /// 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
|
266 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
|
267 &'a self, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
268 py: Python<'a>, |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
269 ) -> $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
|
270 use cpython::PythonObject; |
1b2200bd06b6
rust-cpython: add safe wrapper representing shared data borrowed from PyObject
Yuya Nishihara <yuya@tcha.org>
parents:
43177
diff
changeset
|
271 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
|
272 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
|
273 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
|
274 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
|
275 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
276 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
277 }; |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
278 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
279 |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
280 /// Manage immutable references to `PyObject` leaked into Python iterators. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
281 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
282 /// This reference will be invalidated once the original value is mutably |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
283 /// borrowed. |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
284 pub struct PyLeaked<T> { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
285 inner: PyObject, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
286 data: Option<T>, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
287 py_shared_state: &'static PySharedState, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
288 /// Generation counter of data `T` captured when PyLeaked is created. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
289 generation: usize, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
290 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
291 |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
292 // DO NOT implement Deref for PyLeaked<T>! Dereferencing PyLeaked |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
293 // without taking Python GIL wouldn't be safe. Also, the underling reference |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
294 // is invalid if generation != py_shared_state.generation. |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
295 |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
296 impl<T> PyLeaked<T> { |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
297 /// # Safety |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
298 /// |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
299 /// The `py_shared_state` must be owned by the `inner` Python object. |
43288
434d7a3e92e3
rust-cpython: make inner functions and structs of ref_sharing private
Yuya Nishihara <yuya@tcha.org>
parents:
43287
diff
changeset
|
300 fn new( |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
301 py: Python, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
302 inner: &PyObject, |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
303 data: T, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
304 py_shared_state: &'static PySharedState, |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
305 ) -> Self { |
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
306 Self { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
307 inner: inner.clone_ref(py), |
43284
ce6dd1cee4c8
rust-cpython: put leaked reference in PyLeakedRef
Yuya Nishihara <yuya@tcha.org>
parents:
43272
diff
changeset
|
308 data: Some(data), |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
309 py_shared_state, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
310 generation: py_shared_state.current_generation(py), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
311 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
312 } |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
313 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
314 /// Immutably borrows the wrapped value. |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
315 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
316 /// Borrowing fails if the underlying reference has been invalidated. |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
317 pub fn try_borrow<'a>( |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
318 &'a self, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
319 py: Python<'a>, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
320 ) -> PyResult<PyLeakedRef<'a, T>> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
321 self.validate_generation(py)?; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
322 Ok(PyLeakedRef { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
323 _borrow: BorrowPyShared::new(py, self.py_shared_state), |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
324 data: self.data.as_ref().unwrap(), |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
325 }) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
326 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
327 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
328 /// Mutably borrows the wrapped value. |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
329 /// |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
330 /// Borrowing fails if the underlying reference has been invalidated. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
331 /// |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
332 /// 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
|
333 /// `get_mut()` is useless since the inner value can't be mutated. |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
334 pub fn try_borrow_mut<'a>( |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
335 &'a mut self, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
336 py: Python<'a>, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
337 ) -> PyResult<PyLeakedRefMut<'a, T>> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
338 self.validate_generation(py)?; |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
339 Ok(PyLeakedRefMut { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
340 _borrow: BorrowPyShared::new(py, self.py_shared_state), |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
341 data: self.data.as_mut().unwrap(), |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
342 }) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
343 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
344 |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
345 /// 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
|
346 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
347 /// 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
|
348 /// iterator of that container. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
349 /// |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
350 /// # Panics |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
351 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
352 /// Panics if the underlying reference has been invalidated. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
353 /// |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
354 /// This is typically called immediately after the `PyLeaked` is obtained. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
355 /// In which case, the reference must be valid and no panic would occur. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
356 /// |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
357 /// # Safety |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
358 /// |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
359 /// 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
|
360 /// It's typically a static reference, but is valid only while the |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
361 /// corresponding `PyLeaked` is alive. Do not copy it out of the |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
362 /// function call. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
363 pub unsafe fn map<U>( |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
364 mut self, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
365 py: Python, |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
366 f: impl FnOnce(T) -> U, |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
367 ) -> PyLeaked<U> { |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
368 // Needs to test the generation value to make sure self.data reference |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
369 // is still intact. |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
370 self.validate_generation(py) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
371 .expect("map() over invalidated leaked reference"); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
372 |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
373 // 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
|
374 // 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
|
375 // 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
|
376 // returned object back to Something<'static>. |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
377 let new_data = f(self.data.take().unwrap()); |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
378 PyLeaked { |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
379 inner: self.inner.clone_ref(py), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
380 data: Some(new_data), |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
381 py_shared_state: self.py_shared_state, |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
382 generation: self.generation, |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
383 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
384 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
385 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
386 fn validate_generation(&self, py: Python) -> PyResult<()> { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
387 if self.py_shared_state.current_generation(py) == self.generation { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
388 Ok(()) |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
389 } else { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
390 Err(PyErr::new::<exc::RuntimeError, _>( |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
391 py, |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
392 "Cannot access to leaked reference after mutation", |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
393 )) |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
394 } |
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
395 } |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
396 } |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
397 |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
398 /// Immutably borrowed reference to a leaked value. |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
399 pub struct PyLeakedRef<'a, T> { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
400 _borrow: BorrowPyShared<'a>, |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
401 data: &'a T, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
402 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
403 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
404 impl<T> Deref for PyLeakedRef<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
405 type Target = T; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
406 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
407 fn deref(&self) -> &T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
408 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
409 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
410 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
411 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
412 /// Mutably borrowed reference to a leaked value. |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
413 pub struct PyLeakedRefMut<'a, T> { |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
414 _borrow: BorrowPyShared<'a>, |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
415 data: &'a mut T, |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
416 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
417 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
418 impl<T> Deref for PyLeakedRefMut<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
419 type Target = T; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
420 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
421 fn deref(&self) -> &T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
422 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
423 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
424 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
425 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
426 impl<T> DerefMut for PyLeakedRefMut<'_, T> { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
427 fn deref_mut(&mut self) -> &mut T { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
428 self.data |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
429 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
430 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
431 |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
432 /// Defines a `py_class!` that acts as a Python iterator over a Rust iterator. |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
433 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
434 /// 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:
42887
diff
changeset
|
435 /// 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:
42887
diff
changeset
|
436 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
437 /// # Parameters |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
438 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
439 /// * `$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:
42887
diff
changeset
|
440 /// * `$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:
42887
diff
changeset
|
441 /// * `$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:
42887
diff
changeset
|
442 /// * `$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:
42887
diff
changeset
|
443 /// 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:
42887
diff
changeset
|
444 /// * `$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:
42887
diff
changeset
|
445 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
446 /// # Example |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
447 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
448 /// ``` |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
449 /// struct MyStruct { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
450 /// inner: HashMap<Vec<u8>, Vec<u8>>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
451 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
452 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
453 /// py_class!(pub class MyType |py| { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
454 /// data inner: PySharedRefCell<MyStruct>; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
455 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
456 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> { |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
457 /// let leaked_ref = self.inner_shared(py).leak_immutable(); |
42891
5ccc08d02280
rust-cpython: leverage py_shared_iterator::from_inner() where appropriate
Yuya Nishihara <yuya@tcha.org>
parents:
42890
diff
changeset
|
458 /// MyTypeItemsIterator::from_inner( |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
459 /// py, |
43285
ffc1fbd7d1f5
rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents:
43284
diff
changeset
|
460 /// unsafe { leaked_ref.map(py, |o| o.iter()) }, |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
461 /// ) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
462 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
463 /// }); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
464 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
465 /// impl MyType { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
466 /// fn translate_key_value( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
467 /// py: Python, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
468 /// res: (&Vec<u8>, &Vec<u8>), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
469 /// ) -> PyResult<Option<(PyBytes, PyBytes)>> { |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
470 /// let (f, entry) = res; |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
471 /// Ok(Some(( |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
472 /// PyBytes::new(py, f), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
473 /// PyBytes::new(py, entry), |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
474 /// ))) |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
475 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
476 /// } |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
477 /// |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
478 /// py_shared_ref!(MyType, MyStruct, inner, MyTypeLeakedRef); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
479 /// |
42889
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42888
diff
changeset
|
480 /// py_shared_iterator!( |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
481 /// MyTypeItemsIterator, |
43422
b9f791090211
rust-cpython: rename PyLeakedRef to PyLeaked
Yuya Nishihara <yuya@tcha.org>
parents:
43289
diff
changeset
|
482 /// PyLeaked<HashMap<'static, Vec<u8>, Vec<u8>>>, |
42888
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
483 /// MyType::translate_key_value, |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
484 /// Option<(PyBytes, PyBytes)> |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
485 /// ); |
67853749961b
rust-cpython: replace dyn Iterator<..> of mapping with concrete type
Yuya Nishihara <yuya@tcha.org>
parents:
42887
diff
changeset
|
486 /// ``` |
42889
ea91a126c803
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42888
diff
changeset
|
487 macro_rules! py_shared_iterator { |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
488 ( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
489 $name: ident, |
43177
5cb8867c9e2b
rust-cpython: move $leaked struct out of macro
Yuya Nishihara <yuya@tcha.org>
parents:
43176
diff
changeset
|
490 $leaked: ty, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
491 $success_func: expr, |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
492 $success_type: ty |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
493 ) => { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
494 py_class!(pub class $name |py| { |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
495 data inner: RefCell<$leaked>; |
42752
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 def __next__(&self) -> PyResult<$success_type> { |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
498 let mut leaked = self.inner(py).borrow_mut(); |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
499 let mut iter = leaked.try_borrow_mut(py)?; |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
500 match iter.next() { |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
501 None => Ok(None), |
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
502 Some(res) => $success_func(py, res), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
503 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
504 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
505 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
506 def __iter__(&self) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
507 Ok(self.clone_ref(py)) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
508 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
509 }); |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
510 |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
511 impl $name { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
512 pub fn from_inner( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
513 py: Python, |
42890
74d67c645278
rust-cpython: remove Option<_> from interface of py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
42889
diff
changeset
|
514 leaked: $leaked, |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
515 ) -> PyResult<Self> { |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
516 Self::create_instance( |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
517 py, |
43426
6f9f15a476a4
rust-cpython: remove useless Option<$leaked> from py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents:
43425
diff
changeset
|
518 RefCell::new(leaked), |
42752
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
519 ) |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
520 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
521 } |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
522 }; |
30320c7bf79f
rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
523 } |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
524 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
525 #[cfg(test)] |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
526 #[cfg(any(feature = "python27-bin", feature = "python3-bin"))] |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
527 mod test { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
528 use super::*; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
529 use cpython::{GILGuard, Python}; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
530 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
531 py_class!(class Owner |py| { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
532 data string: PySharedRefCell<String>; |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
533 }); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
534 py_shared_ref!(Owner, String, string, string_shared); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
535 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
536 fn prepare_env() -> (GILGuard, Owner) { |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
537 let gil = Python::acquire_gil(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
538 let py = gil.python(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
539 let owner = |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
540 Owner::create_instance(py, PySharedRefCell::new("new".to_owned())) |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
541 .unwrap(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
542 (gil, owner) |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
543 } |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
544 |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
545 #[test] |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
546 fn test_leaked_borrow() { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
547 let (gil, owner) = prepare_env(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
548 let py = gil.python(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
549 let leaked = owner.string_shared(py).leak_immutable(); |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
550 let leaked_ref = leaked.try_borrow(py).unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
551 assert_eq!(*leaked_ref, "new"); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
552 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
553 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
554 #[test] |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
555 fn test_leaked_borrow_mut() { |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
556 let (gil, owner) = prepare_env(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
557 let py = gil.python(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
558 let leaked = owner.string_shared(py).leak_immutable(); |
43423
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
559 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
560 let mut leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
561 assert_eq!(leaked_ref.next(), Some('n')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
562 assert_eq!(leaked_ref.next(), Some('e')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
563 assert_eq!(leaked_ref.next(), Some('w')); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
564 assert_eq!(leaked_ref.next(), None); |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
565 } |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
566 |
945d4dba5e78
rust-cpython: add stub wrapper that'll prevent leaked data from being mutated
Yuya Nishihara <yuya@tcha.org>
parents:
43422
diff
changeset
|
567 #[test] |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
568 fn test_leaked_borrow_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
569 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
570 let py = gil.python(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
571 let leaked = owner.string_shared(py).leak_immutable(); |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
572 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
573 assert!(leaked.try_borrow(py).is_err()); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
574 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
575 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
576 #[test] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
577 fn test_leaked_borrow_mut_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
578 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
579 let py = gil.python(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
580 let leaked = owner.string_shared(py).leak_immutable(); |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
581 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
582 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
583 assert!(leaked_iter.try_borrow_mut(py).is_err()); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
584 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
585 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
586 #[test] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
587 #[should_panic(expected = "map() over invalidated leaked reference")] |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
588 fn test_leaked_map_after_mut() { |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
589 let (gil, owner) = prepare_env(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
590 let py = gil.python(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
591 let leaked = owner.string_shared(py).leak_immutable(); |
43424
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
592 owner.string_shared(py).borrow_mut().unwrap().clear(); |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
593 let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
594 } |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
595 |
0836efe4967b
rust-cpython: add generation counter to leaked reference
Yuya Nishihara <yuya@tcha.org>
parents:
43423
diff
changeset
|
596 #[test] |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
597 fn test_borrow_mut_while_leaked_ref() { |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
598 let (gil, owner) = prepare_env(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
599 let py = gil.python(); |
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
600 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
601 let leaked = owner.string_shared(py).leak_immutable(); |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
602 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
603 let _leaked_ref = leaked.try_borrow(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
604 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
605 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
606 let _leaked_ref2 = leaked.try_borrow(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
607 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
608 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
609 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
610 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
611 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
612 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
613 |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
614 #[test] |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
615 fn test_borrow_mut_while_leaked_ref_mut() { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
616 let (gil, owner) = prepare_env(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
617 let py = gil.python(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
618 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
619 let leaked = owner.string_shared(py).leak_immutable(); |
43425
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
620 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
621 { |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
622 let _leaked_ref = leaked_iter.try_borrow_mut(py).unwrap(); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
623 assert!(owner.string_shared(py).borrow_mut().is_err()); |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
624 } |
ed50f2c31a4c
rust-cpython: allow mutation unless leaked reference is borrowed
Yuya Nishihara <yuya@tcha.org>
parents:
43424
diff
changeset
|
625 assert!(owner.string_shared(py).borrow_mut().is_ok()); |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
626 } |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
627 |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
628 #[test] |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
629 #[should_panic(expected = "mutably borrowed")] |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
630 fn test_leak_while_borrow_mut() { |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
631 let (gil, owner) = prepare_env(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
632 let py = gil.python(); |
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
633 let _mut_ref = owner.string_shared(py).borrow_mut(); |
43430
8418b77132c1
rust-cpython: remove useless PyResult<> from leak_immutable()
Yuya Nishihara <yuya@tcha.org>
parents:
43429
diff
changeset
|
634 owner.string_shared(py).leak_immutable(); |
43427
b7ab3a0a9e57
rust-cpython: leverage RefCell::borrow() to guarantee there's no mutable ref
Yuya Nishihara <yuya@tcha.org>
parents:
43426
diff
changeset
|
635 } |
43289
8d432d3a2d7c
rust-cpython: prepare for writing tests that require libpython
Yuya Nishihara <yuya@tcha.org>
parents:
43288
diff
changeset
|
636 } |