Mercurial > public > mercurial-scm > hg-stable
annotate rust/pyo3-sharedref/src/lib.rs @ 52640:78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
We take the existing doc-comment from rust-cpython and make it
compile (validated by `cargo test`). With the added explanations,
the ordinary comment was no longer useful, we could therefore
remove it.
The new explanation stresses that "not leaking the internal faked
reference" is definitely not enough, because the problem is about
*all references* that can be derived from it.
We ended up duplicating the explanation, because that is a way
to ensure that people do not miss it. Also, it was a bit misleading
that the previous example was for `try_borrow_mut()`, so we made
a similar, simpler one for `try_borrow()`.
author | Georges Racinet <georges.racinet@cloudcrane.io> |
---|---|
date | Mon, 16 Dec 2024 13:08:55 +0100 |
parents | 76a0bdb0e4ca |
children | 189491cea922 |
rev | line source |
---|---|
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
1 // Copyright (c) 2019 Raphaël Gomès <rgomes@octobus.net>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
2 // Yuya Nishihara <yuya@tcha.org> |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
3 // 2024 Georges Racinet <georges.racinet@cloudcrane.io> |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
4 // |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
5 // Permission is hereby granted, free of charge, to any person obtaining a copy |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
6 // of this software and associated documentation files (the "Software"), to |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
7 // deal in the Software without restriction, including without limitation the |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
9 // sell copies of the Software, and to permit persons to whom the Software is |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
10 // furnished to do so, subject to the following conditions: |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
11 // |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
12 // The above copyright notice and this permission notice shall be included in |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
13 // all copies or substantial portions of the Software. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
14 // |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
21 // IN THE SOFTWARE. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
22 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
23 //! Utility to share Rust reference across Python objects. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
24 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
25 use pyo3::exceptions::PyRuntimeError; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
26 use pyo3::prelude::*; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
27 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
28 use std::ops::{Deref, DerefMut}; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
29 use std::sync::atomic::{AtomicUsize, Ordering}; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
30 use std::sync::{ |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
31 RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError, TryLockResult, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
32 }; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
33 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
34 /// A mutable memory location shareable immutably across Python objects. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
35 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
36 /// This data structure is meant to be used as a field in a Python class |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
37 /// definition. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
38 /// It provides interior mutability in a way that allows it to be immutably |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
39 /// referenced by other Python objects defined in Rust than its owner, in |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
40 /// a more general form than references to the whole data. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
41 /// These immutable references are stored in the referencing Python objects as |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
42 /// [`SharedByPyObject`] fields. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
43 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
44 /// The primary use case is to implement a Python iterator over a Rust |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
45 /// iterator: since a Python object cannot hold a lifetime-bound object, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
46 /// `Iter<'a, T>` cannot be a data field of the Python iterator object. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
47 /// While `&'a T` can be replaced with [`std::sync::Arc`], this is typically |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
48 /// not suited for more complex objects that are created from such references |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
49 /// and re-expose the lifetime on their types, such as iterators. |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
50 /// The [`PyShareableRef::share_immutable()`] and |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
51 /// [`SharedByPyObject::map()`] methods provide a way around this issue. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
52 /// |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
53 /// [`PyShareable`] is [`Sync`]. It works internally with locks and |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
54 /// a "generation" counter that keeps track of mutations. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
55 /// |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
56 /// [`PyShareable`] is merely a data struct to be stored in its |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
57 /// owner Python object. |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
58 /// Any further operation will be performed through [`PyShareableRef`], which |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
59 /// is a lifetime-bound reference to the [`PyShareable`]. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
60 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
61 /// # Example |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
62 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
63 /// ``` |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
64 /// use pyo3::prelude::*; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
65 /// use pyo3_sharedref::*; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
66 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
67 /// use pyo3::ffi::c_str; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
68 /// use pyo3::types::PyDictMethods; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
69 /// use pyo3::types::{PyDict, PyTuple}; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
70 /// use std::collections::{hash_set::Iter as IterHashSet, HashSet}; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
71 /// use pyo3::exceptions::PyRuntimeError; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
72 /// use std::ffi::CStr; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
73 /// use std::vec::Vec; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
74 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
75 /// #[pyclass(sequence)] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
76 /// struct Set { |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
77 /// rust_set: PyShareable<HashSet<i32>>, |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
78 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
79 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
80 /// #[pymethods] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
81 /// impl Set { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
82 /// #[new] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
83 /// fn new(values: &Bound<'_, PyTuple>) -> PyResult<Self> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
84 /// let as_vec = values.extract::<Vec<i32>>()?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
85 /// let s: HashSet<_> = as_vec.iter().copied().collect(); |
52633
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
86 /// Ok(Self { rust_set: s.into() }) |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
87 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
88 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
89 /// fn __iter__(slf: &Bound<'_, Self>) -> SetIterator { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
90 /// SetIterator::new(slf) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
91 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
92 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
93 /// fn add(slf: &Bound<'_, Self>, i: i32) -> PyResult<()> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
94 /// let rust_set = &slf.borrow().rust_set; |
52633
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
95 /// let shared_ref = unsafe { rust_set.borrow_with_owner(slf) }; |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
96 /// let mut set_ref = shared_ref.write(); |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
97 /// set_ref.insert(i); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
98 /// Ok(()) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
99 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
100 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
101 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
102 /// #[pyclass] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
103 /// struct SetIterator { |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
104 /// rust_iter: SharedByPyObject<IterHashSet<'static, i32>>, |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
105 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
106 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
107 /// #[pymethods] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
108 /// impl SetIterator { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
109 /// #[new] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
110 /// fn new(s: &Bound<'_, Set>) -> Self { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
111 /// let py = s.py(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
112 /// let rust_set = &s.borrow().rust_set; |
52637
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
113 /// let iter = unsafe { rust_set.share_map(s, |o| o.iter()) }; |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
114 /// Self { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
115 /// rust_iter: iter.into(), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
116 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
117 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
118 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
119 /// fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
120 /// slf |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
121 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
122 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
123 /// fn __next__(mut slf: PyRefMut<'_, Self>) -> PyResult<Option<i32>> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
124 /// let py = slf.py(); |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
125 /// let shared = &mut slf.rust_iter; |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
126 /// let mut inner = unsafe { shared.try_borrow_mut(py) }?; |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
127 /// Ok(inner.next().copied()) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
128 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
129 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
130 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
131 /// /// a shortcut similar to `[pyo3::py_run!]`, allowing inspection of PyErr |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
132 /// fn py_run(statement: &CStr, locals: &Bound<'_, PyDict>) -> PyResult<()> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
133 /// locals.py().run(statement, None, Some(locals)) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
134 /// } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
135 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
136 /// # pyo3::prepare_freethreaded_python(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
137 /// Python::with_gil(|py| { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
138 /// let tuple = PyTuple::new(py, vec![2, 1, 2])?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
139 /// let set = Bound::new(py, Set::new(&tuple)?)?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
140 /// let iter = Bound::new(py, Set::__iter__(&set))?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
141 /// let locals = PyDict::new(py); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
142 /// locals.set_item("rust_set", set).unwrap(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
143 /// locals.set_item("rust_iter", iter).unwrap(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
144 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
145 /// /// iterating on our Rust set just works |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
146 /// py_run( |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
147 /// c_str!("assert sorted(i for i in rust_iter) == [1, 2]"), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
148 /// &locals, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
149 /// )?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
150 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
151 /// /// however, if any mutation occurs on the Rust set, the iterator |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
152 /// /// becomes invalid. Attempts to use it raise `RuntimeError`. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
153 /// py_run(c_str!("rust_set.add(3)"), &locals)?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
154 /// let err = py_run(c_str!("next(rust_iter)"), &locals).unwrap_err(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
155 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
156 /// let exc_repr = format!("{:?}", err.value(py)); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
157 /// assert_eq!( |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
158 /// exc_repr, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
159 /// "RuntimeError('Cannot access to shared reference after mutation')" |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
160 /// ); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
161 /// # Ok::<(), PyErr>(()) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
162 /// }) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
163 /// # .expect("This example should not return an error"); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
164 /// ``` |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
165 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
166 /// The borrow rules are enforced dynamically in a similar manner to the |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
167 /// Python iterator. |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
168 /// |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
169 /// [`PyShareable`] is merely a data struct to be stored in a Python object. |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
170 /// Any further operation will be performed through [PyShareableRef], which is |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
171 /// a lifetime-bound reference to the [`PyShareable`]. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
172 #[derive(Debug)] |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
173 pub struct PyShareable<T: ?Sized> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
174 state: PySharedState, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
175 data: RwLock<T>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
176 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
177 |
52637
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
178 impl<T: 'static> PyShareable<T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
179 /// Borrows the shared data and its state, keeping a reference |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
180 /// on the owner Python object. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
181 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
182 /// # Safety |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
183 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
184 /// The `data` must be owned by the `owner`. Otherwise, calling |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
185 /// `share_immutable()` on the shared ref would create an invalid |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
186 /// reference. |
52633
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
187 pub unsafe fn borrow_with_owner<'py>( |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
188 &'py self, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
189 owner: &'py Bound<'py, PyAny>, |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
190 ) -> PyShareableRef<'py, T> { |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
191 PyShareableRef { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
192 owner, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
193 state: &self.state, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
194 data: &self.data, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
195 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
196 } |
52637
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
197 |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
198 /// Share for other Python objects |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
199 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
200 /// # Safety |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
201 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
202 /// The `data` must be owned by the `owner`. Otherwise, the resulting |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
203 /// [`SharedByPyObject`] would contain an invalid reference. |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
204 pub unsafe fn share<'py>( |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
205 &'py self, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
206 owner: &'py Bound<'py, PyAny>, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
207 ) -> SharedByPyObject<&'static T> { |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
208 self.borrow_with_owner(owner).share_immutable() |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
209 } |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
210 |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
211 /// Share for other Python objects, transforming the inner data |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
212 /// with a closure |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
213 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
214 /// # Safety |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
215 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
216 /// The `data` must be owned by the `owner`. Otherwise, the resulting |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
217 /// [`SharedByPyObject`] would contain an invalid reference. |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
218 pub unsafe fn share_map<'py, U>( |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
219 &'py self, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
220 owner: &'py Bound<'py, PyAny>, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
221 f: impl FnOnce(&'static T) -> U, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
222 ) -> SharedByPyObject<U> { |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
223 self.share(owner).map(owner.py(), f) |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
224 } |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
225 |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
226 /// # Safety |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
227 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
228 /// The `data` must be owned by the `owner`. Otherwise, the resulting |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
229 /// [`SharedByPyObject`] would contain an invalid reference. |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
230 pub unsafe fn try_share<'py>( |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
231 &'py self, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
232 owner: &'py Bound<'py, PyAny>, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
233 ) -> Result<SharedByPyObject<&'static T>, TryShareError> { |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
234 self.borrow_with_owner(owner).try_share_immutable() |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
235 } |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
236 |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
237 /// # Safety |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
238 /// |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
239 /// The `data` must be owned by the `owner`. Otherwise, the resulting |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
240 /// [`SharedByPyObject`] would contain an invalid reference. |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
241 pub unsafe fn try_share_map<'py, U>( |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
242 &'py self, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
243 owner: &'py Bound<'py, PyAny>, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
244 f: impl FnOnce(&'static T) -> U, |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
245 ) -> Result<SharedByPyObject<U>, TryShareError> { |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
246 Ok(self.try_share(owner)?.map(owner.py(), f)) |
a945845137b1
rust-pyo3-sharedref: share/map methods on PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52636
diff
changeset
|
247 } |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
248 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
249 |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
250 impl<T> From<T> for PyShareable<T> { |
52633
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
251 fn from(value: T) -> Self { |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
252 Self { |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
253 state: PySharedState::new(), |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
254 data: value.into(), |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
255 } |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
256 } |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
257 } |
d85514a88706
rust-pyo3-sharedref: reworked constructors
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52631
diff
changeset
|
258 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
259 /// Errors that can happen in `share_immutable()` |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
260 #[derive(Debug, PartialEq, Eq)] |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
261 pub enum TryShareError { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
262 /// The inner lock is poisoned and we do not want to implement recovery |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
263 InnerLockPoisoned, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
264 /// The inner lock would block and we are expecting to take it immediately |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
265 InnerLockWouldBlock, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
266 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
267 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
268 impl<T> From<TryLockError<T>> for TryShareError { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
269 fn from(e: TryLockError<T>) -> Self { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
270 match e { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
271 TryLockError::Poisoned(_) => Self::InnerLockPoisoned, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
272 TryLockError::WouldBlock => Self::InnerLockWouldBlock, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
273 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
274 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
275 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
276 |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
277 /// A reference to [`PyShareable`] and its legit owner Python object. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
278 /// |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
279 /// This is a lifetime-bound reference to the [PyShareable] data field, |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
280 /// and could be created by an automatically generated accessor when |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
281 /// we make one. |
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
282 pub struct PyShareableRef<'py, T: 'py + ?Sized> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
283 owner: &'py Bound<'py, PyAny>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
284 state: &'py PySharedState, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
285 data: &'py RwLock<T>, // TODO perhaps this needs Pin |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
286 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
287 |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
288 impl<'py, T: ?Sized> PyShareableRef<'py, T> { |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
289 /// Take the lock on the wrapped value for read-only operations. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
290 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
291 /// # Panics |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
292 /// |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
293 /// Panics if the lock is currently held for write operations. |
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
294 pub fn read(&self) -> RwLockReadGuard<'py, T> { |
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
295 self.try_read().expect("already mutably borrowed") |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
296 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
297 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
298 /// Immutably borrows the wrapped value, returning an error if the value |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
299 /// is currently mutably borrowed. |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
300 pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<'py, T>> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
301 // state isn't involved since |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
302 // - data.try_read() would fail if self is mutably borrowed, |
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
303 // - and data.try_write() would fail while self is borrowed. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
304 self.data.try_read() |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
305 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
306 |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
307 /// Take the lock on the wrapped value for write operations. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
308 /// |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
309 /// Any existing shared references will be invalidated. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
310 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
311 /// # Panics |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
312 /// |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
313 /// Panics if the lock is currently held. |
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
314 pub fn write(&self) -> RwLockWriteGuard<'py, T> { |
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
315 self.try_write().expect("already borrowed") |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
316 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
317 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
318 /// Mutably borrows the wrapped value, returning an error if the value |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
319 /// is currently borrowed. |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
320 pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'py, T>> { |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
321 // the value may be immutably borrowed through SharedByPyObject |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
322 if self.state.current_borrow_count(self.py()) > 0 { |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
323 // propagate borrow-by-shared state to data to get BorrowMutError |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
324 let _dummy = self.data.read(); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
325 let _unused = self.data.try_write()?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
326 unreachable!("BorrowMutError should have been returned"); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
327 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
328 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
329 let data_ref = self.data.try_write()?; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
330 self.state.increment_generation(self.py()); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
331 Ok(data_ref) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
332 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
333 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
334 /// Creates an immutable reference which is not bound to lifetime. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
335 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
336 /// # Panics |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
337 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
338 /// Panics if the value is currently mutably borrowed. |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
339 pub fn share_immutable(&self) -> SharedByPyObject<&'static T> { |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
340 self.try_share_immutable() |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
341 .expect("already mutably borrowed") |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
342 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
343 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
344 /// Creates an immutable reference which is not bound to lifetime, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
345 /// returning an error if the value is currently mutably borrowed. |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
346 pub fn try_share_immutable( |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
347 &self, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
348 ) -> Result<SharedByPyObject<&'static T>, TryShareError> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
349 // make sure self.data isn't mutably borrowed; otherwise the |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
350 // generation number wouldn't be trusted. |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
351 let data_ref = self.try_read()?; |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
352 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
353 // keep reference to the owner so the data and state are alive, |
52634
d1e304025b90
rust-pyo3-sharedref: replaced borrow/borrow_mut with RwLock namings
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52633
diff
changeset
|
354 // but the data pointer can be invalidated by write(). |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
355 // the state wouldn't since it is immutable. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
356 let state_ptr: *const PySharedState = self.state; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
357 let data_ptr: *const T = &*data_ref; |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
358 Ok(SharedByPyObject::<&'static T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
359 owner: self.owner.clone().unbind(), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
360 state: unsafe { &*state_ptr }, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
361 generation: self.state.current_generation(self.py()), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
362 data: unsafe { &*data_ptr }, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
363 }) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
364 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
365 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
366 /// Retrieve the GIL handle |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
367 fn py(&self) -> Python<'py> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
368 // Since this is a smart pointer implying the GIL lifetime, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
369 // we might as well use `assume_gil_acquired`, but the method |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
370 // of `Bound` does it for us. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
371 self.owner.py() |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
372 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
373 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
374 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
375 /// The shared state between Python and Rust |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
376 /// |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
377 /// `PySharedState` is owned by `PyShareable`, and is shared across its |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
378 /// derived references. The consistency of these references are guaranteed |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
379 /// as follows: |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
380 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
381 /// - The immutability of `PycCass` object fields. Any mutation of |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
382 /// [`PyShareable`] is allowed only through its `write()`. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
383 /// - The `py: Python<'_>` token, which makes sure that any data access is |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
384 /// synchronized by the GIL. |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
385 /// - The underlying `RefCell`, which prevents `PyShareable` value from being |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
386 /// directly borrowed or shared while it is mutably borrowed. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
387 /// - The `borrow_count`, which is the number of references borrowed from |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
388 /// `SharedByPyObject`. Just like `RefCell`, mutation is prohibited while |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
389 /// `SharedByPyObject` is borrowed. |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
390 /// - The `generation` counter, which increments on `write()`. |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
391 /// `SharedByPyObject` |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
392 #[derive(Debug)] |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
393 struct PySharedState { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
394 // The counter variable could be Cell<usize> since any operation on |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
395 // PySharedState is synchronized by the GIL, but being "atomic" makes |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
396 // PySharedState inherently Sync. The ordering requirement doesn't |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
397 // matter thanks to the GIL. That's why Ordering::Relaxed is used |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
398 // everywhere. |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
399 /// The number of immutable references borrowed through shared reference. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
400 borrow_count: AtomicUsize, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
401 /// The mutation counter of the underlying value. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
402 generation: AtomicUsize, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
403 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
404 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
405 impl PySharedState { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
406 const fn new() -> PySharedState { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
407 PySharedState { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
408 borrow_count: AtomicUsize::new(0), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
409 generation: AtomicUsize::new(0), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
410 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
411 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
412 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
413 fn current_borrow_count(&self, _py: Python) -> usize { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
414 self.borrow_count.load(Ordering::Relaxed) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
415 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
416 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
417 fn increase_borrow_count(&self, _py: Python) { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
418 // this wraps around if there are more than usize::MAX borrowed |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
419 // references, which shouldn't happen due to memory limit. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
420 self.borrow_count.fetch_add(1, Ordering::Relaxed); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
421 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
422 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
423 fn decrease_borrow_count(&self, _py: Python) { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
424 let prev_count = self.borrow_count.fetch_sub(1, Ordering::Relaxed); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
425 assert!(prev_count > 0); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
426 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
427 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
428 fn current_generation(&self, _py: Python) -> usize { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
429 self.generation.load(Ordering::Relaxed) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
430 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
431 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
432 fn increment_generation(&self, py: Python) { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
433 assert_eq!(self.current_borrow_count(py), 0); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
434 // this wraps around to the same value if mutably borrowed |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
435 // usize::MAX times, which wouldn't happen in practice. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
436 self.generation.fetch_add(1, Ordering::Relaxed); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
437 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
438 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
439 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
440 /// Helper to keep the borrow count updated while the shared object is |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
441 /// immutably borrowed without using the `RwLock` interface. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
442 struct BorrowPyShared<'a> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
443 py: Python<'a>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
444 state: &'a PySharedState, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
445 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
446 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
447 impl<'a> BorrowPyShared<'a> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
448 fn new(py: Python<'a>, state: &'a PySharedState) -> BorrowPyShared<'a> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
449 state.increase_borrow_count(py); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
450 BorrowPyShared { py, state } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
451 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
452 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
453 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
454 impl<'a> Drop for BorrowPyShared<'a> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
455 fn drop(&mut self) { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
456 self.state.decrease_borrow_count(self.py); |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
457 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
458 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
459 |
52635
c25d345f5aa5
rust-pyo3-sharedref: renamed PySharedRefCell to PyShareable
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52634
diff
changeset
|
460 /// An immutable reference to [`PyShareable`] value, not bound to lifetime. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
461 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
462 /// The reference will be invalidated once the original value is mutably |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
463 /// borrowed. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
464 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
465 /// # Safety |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
466 /// |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
467 /// Even though [`SharedByPyObject`] tries to enforce the real lifetime of the |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
468 /// underlying object, the object having the artificial `'static` lifetime |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
469 /// may be exposed to your Rust code. You must be careful to not make a bare |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
470 /// reference outlive the actual object lifetime. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
471 /// |
52640
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
472 /// See [`Self::try_borrow_mut()`] for an example of the kind of trouble that |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
473 /// can arise. |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
474 pub struct SharedByPyObject<T: ?Sized> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
475 owner: PyObject, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
476 state: &'static PySharedState, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
477 /// Generation counter of data `T` captured when SharedByPyObject is |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
478 /// created. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
479 generation: usize, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
480 /// Underlying data of artificial lifetime, which is valid only when |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
481 /// state.generation == self.generation. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
482 data: T, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
483 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
484 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
485 // DO NOT implement Deref for SharedByPyObject<T>! Dereferencing |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
486 // SharedByPyObject without taking Python GIL wouldn't be safe. Also, the |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
487 // underling reference is invalid if generation != state.generation. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
488 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
489 impl<T: ?Sized> SharedByPyObject<T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
490 // No panicking version of borrow() and borrow_mut() are implemented |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
491 // because the underlying value is supposed to be mutated in Python |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
492 // world, and the Rust library designer can't prevent it. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
493 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
494 /// Immutably borrows the wrapped value. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
495 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
496 /// Borrowing fails if the underlying reference has been invalidated. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
497 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
498 /// # Safety |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
499 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
500 /// The lifetime of the innermost object is artificial. Do not obtain and |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
501 /// copy it out of the borrow scope. |
52640
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
502 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
503 /// The lifetime of the innermost object is artificial. Do not obtain and |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
504 /// copy it out of the borrow scope. More generally, the returned `&T` |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
505 /// may have a method returning an inner reference, which would typically |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
506 /// be `'static` and not safe without the `owner` Python object, so the |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
507 /// problem might be less obvious than in the example below. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
508 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
509 /// The following example does compile and illustrates the problem. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
510 /// In this case, the data is a `Vec<String>` and the leaked reference |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
511 /// `&'static str`, which points to some element of the vector. This |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
512 /// illustrates that the leaks are not necessarily to the whole of the |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
513 /// shared data. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
514 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
515 /// ```no_run |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
516 /// # use pyo3::prelude::*; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
517 /// # use pyo3_sharedref::PyShareable; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
518 /// #[pyclass] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
519 /// struct Owner { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
520 /// value: PyShareable<Vec<String>> |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
521 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
522 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
523 /// #[pymethods] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
524 /// impl Owner { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
525 /// #[new] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
526 /// fn new(s: &str) -> Self { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
527 /// let split: Vec<_> = s.split(' ').map(String::from).collect(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
528 /// Self { value: split.into() } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
529 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
530 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
531 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
532 /// const EMPTY: &'static str = ""; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
533 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
534 /// let mut outer = EMPTY; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
535 /// Python::with_gil(|py| { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
536 /// let owner = Bound::new(py, Owner::new("hello")).unwrap(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
537 /// let shareable = &owner.borrow().value; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
538 /// let shared = unsafe { shareable.share(&owner) }; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
539 /// { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
540 /// let inner = unsafe { shared.try_borrow(py) }.unwrap(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
541 /// outer = &inner[0]; // Bad, &'static str does outlive the scope |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
542 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
543 /// }); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
544 /// ``` |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
545 pub unsafe fn try_borrow<'a>( |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
546 &'a self, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
547 py: Python<'a>, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
548 ) -> PyResult<SharedByPyObjectRef<'a, T>> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
549 self.validate_generation(py)?; |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
550 Ok(SharedByPyObjectRef { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
551 _borrow: BorrowPyShared::new(py, self.state), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
552 data: &self.data, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
553 }) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
554 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
555 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
556 /// Mutably borrows the wrapped value. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
557 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
558 /// Borrowing fails if the underlying reference has been invalidated. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
559 /// |
52640
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
560 /// Typically `T` would be an iterator obtained by the [`Self::map`] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
561 /// method. |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
562 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
563 /// # Safety |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
564 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
565 /// The lifetime of the innermost object is artificial. Do not obtain and |
52640
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
566 /// copy it out of the borrow scope. More generally, the returned `&T` |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
567 /// may have a method returning an inner reference, which would typically |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
568 /// be `'static` and not safe without the `owner` Python object, so the |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
569 /// problem might be less obvious than in the example below. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
570 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
571 /// The following example does compile and illustrates the problem. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
572 /// It is very close to the example given in [`Self::try_borrow`] because |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
573 /// the problem does not arise from the mutability of the reference |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
574 /// returned by this function. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
575 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
576 /// In this case, the data is a `Vec<String>` and the leaked reference |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
577 /// `&'static str`, which points to some element of the vector. This |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
578 /// illustrates that the leaks are not necessarily to the whole of the |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
579 /// shared data. |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
580 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
581 /// ```no_run |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
582 /// # use pyo3::prelude::*; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
583 /// # use pyo3_sharedref::PyShareable; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
584 /// #[pyclass] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
585 /// struct Owner { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
586 /// value: PyShareable<Vec<String>> |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
587 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
588 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
589 /// #[pymethods] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
590 /// impl Owner { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
591 /// #[new] |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
592 /// fn new(s: &str) -> Self { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
593 /// let split: Vec<_> = s.split(' ').map(String::from).collect(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
594 /// Self { value: split.into() } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
595 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
596 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
597 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
598 /// const EMPTY: &'static str = ""; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
599 /// |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
600 /// let mut outer = EMPTY; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
601 /// Python::with_gil(|py| { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
602 /// let owner = Bound::new(py, Owner::new("hello")).unwrap(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
603 /// let shareable = &owner.borrow().value; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
604 /// let shared = unsafe { shareable.share(&owner) }; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
605 /// let mut shared_iter = unsafe { shared.map(py, |o| o.iter()) }; |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
606 /// { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
607 /// let mut iter = unsafe { |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
608 /// shared_iter.try_borrow_mut(py) |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
609 /// }.unwrap(); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
610 /// let inner = iter.next().unwrap(); // Good, in borrow scope |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
611 /// outer = inner; // Bad, &'static str does outlive the scope |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
612 /// } |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
613 /// }); |
78b2894cd58c
rust-pyo3-sharedref: demonstrate SharedByPyObject borrow unsafety
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52639
diff
changeset
|
614 /// ``` |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
615 pub unsafe fn try_borrow_mut<'a>( |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
616 &'a mut self, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
617 py: Python<'a>, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
618 ) -> PyResult<SharedByPyObjectRefMut<'a, T>> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
619 self.validate_generation(py)?; |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
620 Ok(SharedByPyObjectRefMut { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
621 _borrow: BorrowPyShared::new(py, self.state), |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
622 data: &mut self.data, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
623 }) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
624 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
625 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
626 fn validate_generation(&self, py: Python) -> PyResult<()> { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
627 if self.state.current_generation(py) == self.generation { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
628 Ok(()) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
629 } else { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
630 Err(PyRuntimeError::new_err( |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
631 "Cannot access to shared reference after mutation", |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
632 )) |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
633 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
634 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
635 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
636 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
637 impl<T> SharedByPyObject<T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
638 /// Converts the inner value by the given function. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
639 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
640 /// Typically `T` is a static reference to a collection, and `U` is an |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
641 /// iterator of that collection. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
642 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
643 /// # Panics |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
644 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
645 /// Panics if the underlying reference has been invalidated. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
646 /// |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
647 /// This is typically called immediately after the `SharedByPyObject` is |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
648 /// obtained. At this time, the reference must be valid and no panic |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
649 /// would occur. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
650 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
651 /// # Safety |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
652 /// |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
653 /// The lifetime of the object passed in to the function `f` is artificial. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
654 /// It's typically a static reference, but is valid only while the |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
655 /// corresponding `SharedByPyObject` is alive. Do not copy it out of the |
52639
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
656 /// function call. For example, the following does compile: |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
657 /// |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
658 /// ```no_run |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
659 /// # use pyo3::prelude::*; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
660 /// # use pyo3_sharedref::PyShareable; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
661 /// #[pyclass] |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
662 /// struct Owner { |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
663 /// value: PyShareable<String> |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
664 /// } |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
665 /// |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
666 /// #[pymethods] |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
667 /// impl Owner { |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
668 /// #[new] |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
669 /// fn new(s: &str) -> Self { |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
670 /// Self { value: s.to_owned().into() } |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
671 /// } |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
672 /// } |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
673 /// |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
674 /// const EMPTY: &'static str = ""; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
675 /// |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
676 /// let mut outer = EMPTY; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
677 /// Python::with_gil(|py| { |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
678 /// let owner = Bound::new(py, Owner::new("hello")).unwrap(); |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
679 /// let shareable = &owner.borrow().value; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
680 /// let shared = unsafe { shareable.share(&owner) }; |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
681 /// |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
682 /// unsafe { shared.map(py, |o| { outer = o }) }; // Bad |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
683 /// }); |
76a0bdb0e4ca
rust-pyo3-sharedref: demonstrating unsafety of map()
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52637
diff
changeset
|
684 /// ``` |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
685 pub unsafe fn map<U>( |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
686 self, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
687 py: Python, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
688 f: impl FnOnce(T) -> U, |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
689 ) -> SharedByPyObject<U> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
690 // Needs to test the generation value to make sure self.data reference |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
691 // is still intact. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
692 self.validate_generation(py) |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
693 .expect("map() over invalidated shared reference"); |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
694 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
695 // f() could make the self.data outlive. That's why map() is unsafe. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
696 // In order to make this function safe, maybe we'll need a way to |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
697 // temporarily restrict the lifetime of self.data and translate the |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
698 // returned object back to Something<'static>. |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
699 let new_data = f(self.data); |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
700 SharedByPyObject { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
701 owner: self.owner, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
702 state: self.state, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
703 generation: self.generation, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
704 data: new_data, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
705 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
706 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
707 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
708 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
709 /// An immutably borrowed reference to a shared value. |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
710 pub struct SharedByPyObjectRef<'a, T: 'a + ?Sized> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
711 _borrow: BorrowPyShared<'a>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
712 data: &'a T, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
713 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
714 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
715 impl<'a, T: ?Sized> Deref for SharedByPyObjectRef<'a, T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
716 type Target = T; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
717 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
718 fn deref(&self) -> &T { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
719 self.data |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
720 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
721 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
722 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
723 /// A mutably borrowed reference to a shared value. |
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
724 pub struct SharedByPyObjectRefMut<'a, T: 'a + ?Sized> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
725 _borrow: BorrowPyShared<'a>, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
726 data: &'a mut T, |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
727 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
728 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
729 impl<'a, T: ?Sized> Deref for SharedByPyObjectRefMut<'a, T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
730 type Target = T; |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
731 |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
732 fn deref(&self) -> &T { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
733 self.data |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
734 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
735 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
736 |
52636
4a73eb3923ac
rust-pyo3-sharedref: renamed UnsafePyLeaked to SharedByPyObject
Georges Racinet <georges.racinet@cloudcrane.io>
parents:
52635
diff
changeset
|
737 impl<'a, T: ?Sized> DerefMut for SharedByPyObjectRefMut<'a, T> { |
52631
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
738 fn deref_mut(&mut self) -> &mut T { |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
739 self.data |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
740 } |
be765f6797cc
rust-pyo3: initial port of PySharedRef
Georges Racinet <georges.racinet@octobus.net>
parents:
diff
changeset
|
741 } |