[−][src]Struct pyo3::once_cell::GILOnceCell
A write-once cell similar to once_cell::OnceCell
.
Unlike once_cell::sync
which blocks threads to achieve thread safety, this implementation
uses the Python GIL to mediate concurrent access. This helps in cases where once_sync
or
lazy_static
's synchronization strategy can lead to deadlocks when interacting with the Python
GIL. For an example, see the FAQ section of the guide.
Example
The following example shows how to use GILOnceCell
to share a reference to a Python list
between threads:
use pyo3::prelude::*; use pyo3::types::PyList; use pyo3::once_cell::GILOnceCell; static LIST_CELL: GILOnceCell<Py<PyList>> = GILOnceCell::new(); pub fn get_shared_list(py: Python) -> &PyList { LIST_CELL .get_or_init(py, || PyList::empty(py).into()) .as_ref(py) }
Implementations
impl<T> GILOnceCell<T>
[src]
pub const fn new() -> Self
[src]
Create a GILOnceCell
which does not yet contain a value.
pub fn get(&self, _py: Python<'_>) -> Option<&T>
[src]
Get a reference to the contained value, or None
if the cell has not yet been written.
pub fn get_or_init<F>(&self, py: Python<'_>, f: F) -> &T where
F: FnOnce() -> T,
[src]
F: FnOnce() -> T,
Get a reference to the contained value, initializing it if needed using the provided closure.
Note that:
- reentrant initialization can cause a stack overflow.
- if f() temporarily releases the GIL (e.g. by calling
Python::import
) then it is possible (and well-defined) that a second thread may also call get_or_init and begin callingf()
. Even when this happensGILOnceCell
guarantees that only one write to the cell ever occurs - other threads will simply discard the value they compute and return the result of the first complete computation. - if f() does not release the GIL and does not panic, it is guaranteed to be called
exactly once, even if multiple threads attempt to call
get_or_init
- if f() can panic but still does not release the GIL, it may be called multiple times, but it is guaranteed that f() will never be called concurrently
pub fn get_mut(&mut self) -> Option<&mut T>
[src]
Get the contents of the cell mutably. This is only possible if the reference to the cell is unique.
pub fn set(&self, _py: Python<'_>, value: T) -> Result<(), T>
[src]
Set the value in the cell.
If the cell has already been written, Err(value)
will be returned containing the new
value which was not written.
Trait Implementations
impl<T: Send> Send for GILOnceCell<T>
[src]
impl<T: Send + Sync> Sync for GILOnceCell<T>
[src]
Auto Trait Implementations
impl<T> !RefUnwindSafe for GILOnceCell<T>
impl<T> Unpin for GILOnceCell<T> where
T: Unpin,
T: Unpin,
impl<T> UnwindSafe for GILOnceCell<T> where
T: UnwindSafe,
T: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T> FromPy<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> IntoPy<U> for T where
U: FromPy<T>,
[src]
U: FromPy<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,