##// END OF EJS Templates
rust: implement vcsgraph::RankedGraph for Index...
rust: implement vcsgraph::RankedGraph for Index Differential Revision: https://phab.mercurial-scm.org/D12210

File last commit:

r48766:4afd6cc4 default
r49708:4346be45 default
Show More
pybytes_deref.rs
56 lines | 1.5 KiB | application/rls-services+xml | RustLexer
Simon Sapin
rust: Move PyBytesWithData out of copy-tracing code...
r48765 use cpython::{PyBytes, Python};
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 use stable_deref_trait::StableDeref;
Simon Sapin
rust: Move PyBytesWithData out of copy-tracing code...
r48765
/// Safe abstraction over a `PyBytes` together with the `&[u8]` slice
/// that borrows it. Implements `Deref<Target = [u8]>`.
///
/// Calling `PyBytes::data` requires a GIL marker but we want to access the
/// data in a thread that (ideally) does not need to acquire the GIL.
/// This type allows separating the call an the use.
///
/// It also enables using a (wrapped) `PyBytes` in GIL-unaware generic code.
pub struct PyBytesDeref {
#[allow(unused)]
keep_alive: PyBytes,
/// Borrows the buffer inside `self.keep_alive`,
/// but the borrow-checker cannot express self-referential structs.
data: *const [u8],
}
impl PyBytesDeref {
pub fn new(py: Python, bytes: PyBytes) -> Self {
Self {
data: bytes.data(py),
keep_alive: bytes,
}
}
pub fn unwrap(self) -> PyBytes {
self.keep_alive
}
}
impl std::ops::Deref for PyBytesDeref {
type Target = [u8];
fn deref(&self) -> &[u8] {
// Safety: the raw pointer is valid as long as the PyBytes is still
// alive, and the returned slice borrows `self`.
unsafe { &*self.data }
}
}
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 unsafe impl StableDeref for PyBytesDeref {}
Simon Sapin
rust: Move PyBytesWithData out of copy-tracing code...
r48765 fn require_send<T: Send>() {}
#[allow(unused)]
fn static_assert_pybytes_is_send() {
require_send::<PyBytes>;
}
// Safety: PyBytes is Send. Raw pointers are not by default,
// but here sending one to another thread is fine since we ensure it stays
// valid.
unsafe impl Send for PyBytesDeref {}