author | Rapha?l Gom?s <rgomes@octobus.net> |
Mon, 30 Oct 2023 11:57:36 +0100 | |
changeset 51219 | fc05dd74e907 |
parent 49933 | be3b545c5cff |
child 52163 | 7346f93be7a4 |
permissions | -rw-r--r-- |
47953
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
1 |
use cpython::{PyBytes, Python}; |
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47953
diff
changeset
|
2 |
use stable_deref_trait::StableDeref; |
47953
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
3 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 |
/// Safe abstraction over a `PyBytes` together with the `&[u8]` slice |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
5 |
/// that borrows it. Implements `Deref<Target = [u8]>`. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 |
/// |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
7 |
/// Calling `PyBytes::data` requires a GIL marker but we want to access the |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
8 |
/// data in a thread that (ideally) does not need to acquire the GIL. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
9 |
/// This type allows separating the call an the use. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 |
/// |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 |
/// It also enables using a (wrapped) `PyBytes` in GIL-unaware generic code. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
12 |
pub struct PyBytesDeref { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
13 |
#[allow(unused)] |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
14 |
keep_alive: PyBytes, |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
16 |
/// Borrows the buffer inside `self.keep_alive`, |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 |
/// but the borrow-checker cannot express self-referential structs. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 |
data: *const [u8], |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 |
impl PyBytesDeref { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
22 |
pub fn new(py: Python, bytes: PyBytes) -> Self { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 |
Self { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 |
data: bytes.data(py), |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 |
keep_alive: bytes, |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
28 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
29 |
pub fn unwrap(self) -> PyBytes { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
30 |
self.keep_alive |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
31 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
32 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
33 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
34 |
impl std::ops::Deref for PyBytesDeref { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
35 |
type Target = [u8]; |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
36 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 |
fn deref(&self) -> &[u8] { |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 |
// Safety: the raw pointer is valid as long as the PyBytes is still |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
39 |
// alive, and the returned slice borrows `self`. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
40 |
unsafe { &*self.data } |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
41 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
42 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
43 |
|
47954
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47953
diff
changeset
|
44 |
unsafe impl StableDeref for PyBytesDeref {} |
4afd6cc447b9
rust: Make OwningDirstateMap generic and move it into hg-core
Simon Sapin <simon.sapin@octobus.net>
parents:
47953
diff
changeset
|
45 |
|
47953
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
46 |
fn require_send<T: Send>() {} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
47 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
48 |
#[allow(unused)] |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
49 |
fn static_assert_pybytes_is_send() { |
49933
be3b545c5cff
rust-clippy: fix remaining warnings in `hg-cpython`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
47954
diff
changeset
|
50 |
#[allow(clippy::no_effect)] |
47953
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
51 |
require_send::<PyBytes>; |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
52 |
} |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
53 |
|
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
54 |
// Safety: PyBytes is Send. Raw pointers are not by default, |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
55 |
// but here sending one to another thread is fine since we ensure it stays |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
56 |
// valid. |
8f031a274cd6
rust: Move PyBytesWithData out of copy-tracing code
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
57 |
unsafe impl Send for PyBytesDeref {} |