pub struct PyMutex<T: ?Sized> { /* private fields */ }Expand description
Wrapper for PyMutex, exposing an RAII guard interface.
Compared with std::sync::Mutex or parking_lot::Mutex, this is a very
stripped-down locking primitive that only supports blocking lock and unlock
operations and does not support try_lock or APIs that depend on
try_lock. For this reason, it is not possible to avoid the possibility of
possibly blocking when calling lock and extreme care must be taken to avoid
introducing a deadlock.
This type is most useful when arbitrary Python code might execute while the lock is held. On the GIL-enabled build, PyMutex will release the GIL if the thread is blocked on acquiring the lock. On the free-threaded build, threads blocked on acquiring a PyMutex will not prevent the garbage collector from running.
§Poisoning
Like std::sync::Mutex, PyMutex implements poisoning. A mutex
is considered poisoned whenever a thread panics while holding the mutex. Once
a mutex is poisoned, all other threads are unable to access the data by
default as it is likely to be tainted (some invariant is not being held).
This means that the lock method returns a Result which indicated whether
the mutex has been poisoned or not. Must usage will simple unwrap() these
results, propagating panics among threads to ensure a possible invalid
invariant is not being observed.
A poisoned mutex, however, does not prevent all access to the underlying
data. The PoisonError type has an into_inner method which will return
the guard that would have otherwise been returned on a successful lock. This
allows access to the data, despite the lock being poisoned.
Implementations§
Source§impl<T> PyMutex<T>
impl<T> PyMutex<T>
Sourcepub fn lock(&self) -> LockResult<PyMutexGuard<'_, T>>
pub fn lock(&self) -> LockResult<PyMutexGuard<'_, T>>
Acquire the mutex, blocking the current thread until it is able to do so.
Sourcepub fn is_locked(&self) -> bool
pub fn is_locked(&self) -> bool
Check if the mutex is locked.
Note that this is only useful for debugging or test purposes and should not be used to make concurrency control decisions, as the lock state may change immediately after the check.
Sourcepub fn into_inner(self) -> LockResult<T>where
T: Sized,
pub fn into_inner(self) -> LockResult<T>where
T: Sized,
Consumes this mutex, returning the underlying data.
§Errors
If another user of this mutex panicked while holding the mutex, then this call will return an error containing the underlying data instead.
Sourcepub fn clear_poison(&self)
pub fn clear_poison(&self)
Clear the poisoned state from a mutex.
If the mutex is poisoned, it will remain poisoned until this function is called. This allows recovering from a poisoned state and marking that it has recovered. For example, if the value is overwritten by a known-good value, then the mutex can be marked as un-poisoned. Or possibly, the value could be inspected to determine if it is in a consistent state, and if so the poison is removed.
Trait Implementations§
impl<T: ?Sized + Send> Send for PyMutex<T>
T must be Send for a PyMutex to be Send because it is possible to acquire
the owned T from the PyMutex via into_inner.
impl<T: ?Sized + Send> Sync for PyMutex<T>
T must be Send for PyMutex to be Sync.
This ensures that the protected data can be accessed safely from multiple threads
without causing data races or other unsafe behavior.
PyMutex<T> provides mutable access to T to one thread at a time. However, it’s essential
for T to be Send because it’s not safe for non-Send structures to be accessed in
this manner. For instance, consider Rc, a non-atomic reference counted smart pointer,
which is not Send. With Rc, we can have multiple copies pointing to the same heap
allocation with a non-atomic reference count. If we were to use Mutex<Rc<_>>, it would
only protect one instance of Rc from shared access, leaving other copies vulnerable
to potential data races.
Also note that it is not necessary for T to be Sync as &T is only made available
to one thread at a time if T is not Sync.
Auto Trait Implementations§
impl<T> !Freeze for PyMutex<T>
impl<T> !RefUnwindSafe for PyMutex<T>
impl<T> Unpin for PyMutex<T>
impl<T> UnwindSafe for PyMutex<T>where
T: UnwindSafe + ?Sized,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more