Struct pyo3::once_cell::GILOnceCell
source · pub struct GILOnceCell<T>(_);
Expand description
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_cell
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.
Note that:
get_or_init
andget_or_try_init
do not protect against infinite recursion from reentrant initialization.- If the initialization function
f
provided toget_or_init
(orget_or_try_init
) temporarily releases the GIL (e.g. by callingPython::import
) then it is possible for a second thread to also begin initializing theGITOnceCell
. Even when this happensGILOnceCell
guarantees that only one write to the cell ever occurs- this is treated as a race, other threads will discard the value they compute and return the result of the first complete computation.
Examples
The following example shows how to use GILOnceCell
to share a reference to a Python list
between threads:
use pyo3::once_cell::GILOnceCell;
use pyo3::prelude::*;
use pyo3::types::PyList;
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§
source§impl<T> GILOnceCell<T>
impl<T> GILOnceCell<T>
sourcepub fn get(&self, _py: Python<'_>) -> Option<&T>
pub fn get(&self, _py: Python<'_>) -> Option<&T>
Get a reference to the contained value, or None
if the cell has not yet been written.
sourcepub fn get_or_init<F>(&self, py: Python<'_>, f: F) -> &Twhere
F: FnOnce() -> T,
pub fn get_or_init<F>(&self, py: Python<'_>, f: F) -> &Twhere
F: FnOnce() -> T,
Get a reference to the contained value, initializing it if needed using the provided closure.
See the type-level documentation for detail on re-entrancy and concurrent initialization.
sourcepub fn get_or_try_init<F, E>(&self, py: Python<'_>, f: F) -> Result<&T, E>where
F: FnOnce() -> Result<T, E>,
pub fn get_or_try_init<F, E>(&self, py: Python<'_>, f: F) -> Result<&T, E>where
F: FnOnce() -> Result<T, E>,
Like get_or_init
, but accepts a fallible initialization function. If it fails, the cell
is left uninitialized.
See the type-level documentation for detail on re-entrancy and concurrent initialization.