rustpython_common/
lock.rs1use lock_api::{
5 MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard, Mutex, MutexGuard, RwLock,
6 RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard,
7};
8
9cfg_if::cfg_if! {
10 if #[cfg(feature = "threading")] {
11 pub use parking_lot::{RawMutex, RawRwLock, RawThreadId};
12
13 pub use std::sync::OnceLock as OnceCell;
14 pub use core::cell::LazyCell;
15 } else {
16 mod cell_lock;
17 pub use cell_lock::{RawCellMutex as RawMutex, RawCellRwLock as RawRwLock, SingleThreadId as RawThreadId};
18
19 pub use core::cell::{LazyCell, OnceCell};
20 }
21}
22
23cfg_if::cfg_if! {
27 if #[cfg(any(feature = "threading", feature = "std"))] {
28 pub use std::sync::LazyLock;
29 } else {
30 pub struct LazyLock<T, F = fn() -> T>(core::cell::LazyCell<T, F>);
31 unsafe impl<T, F> Sync for LazyLock<T, F> {}
36
37 impl<T, F: FnOnce() -> T> LazyLock<T, F> {
38 pub const fn new(f: F) -> Self { Self(core::cell::LazyCell::new(f)) }
39 pub fn force(this: &Self) -> &T { core::cell::LazyCell::force(&this.0) }
40 }
41
42 impl<T, F: FnOnce() -> T> core::ops::Deref for LazyLock<T, F> {
43 type Target = T;
44 fn deref(&self) -> &T { &self.0 }
45 }
46 }
47}
48
49mod immutable_mutex;
50pub use immutable_mutex::*;
51mod thread_mutex;
52pub use thread_mutex::*;
53
54pub type PyMutex<T> = Mutex<RawMutex, T>;
55pub type PyMutexGuard<'a, T> = MutexGuard<'a, RawMutex, T>;
56pub type PyMappedMutexGuard<'a, T> = MappedMutexGuard<'a, RawMutex, T>;
57pub type PyImmutableMappedMutexGuard<'a, T> = ImmutableMappedMutexGuard<'a, RawMutex, T>;
58pub type PyThreadMutex<T> = ThreadMutex<RawMutex, RawThreadId, T>;
59pub type PyThreadMutexGuard<'a, T> = ThreadMutexGuard<'a, RawMutex, RawThreadId, T>;
60pub type PyMappedThreadMutexGuard<'a, T> = MappedThreadMutexGuard<'a, RawMutex, RawThreadId, T>;
61
62pub type PyRwLock<T> = RwLock<RawRwLock, T>;
63pub type PyRwLockUpgradableReadGuard<'a, T> = RwLockUpgradableReadGuard<'a, RawRwLock, T>;
64pub type PyRwLockReadGuard<'a, T> = RwLockReadGuard<'a, RawRwLock, T>;
65pub type PyMappedRwLockReadGuard<'a, T> = MappedRwLockReadGuard<'a, RawRwLock, T>;
66pub type PyRwLockWriteGuard<'a, T> = RwLockWriteGuard<'a, RawRwLock, T>;
67pub type PyMappedRwLockWriteGuard<'a, T> = MappedRwLockWriteGuard<'a, RawRwLock, T>;
68
69pub unsafe fn zero_reinit_after_fork<T>(lock: *const T) {
85 unsafe {
86 core::ptr::write_bytes(lock as *mut u8, 0, core::mem::size_of::<T>());
87 }
88}
89
90#[cfg(unix)]
97pub unsafe fn reinit_mutex_after_fork<T: ?Sized>(mutex: &PyMutex<T>) {
98 unsafe { zero_reinit_after_fork(mutex.raw()) }
99}
100
101#[cfg(unix)]
108pub unsafe fn reinit_rwlock_after_fork<T: ?Sized>(rwlock: &PyRwLock<T>) {
109 unsafe { zero_reinit_after_fork(rwlock.raw()) }
110}
111
112#[cfg(unix)]
123pub unsafe fn reinit_thread_mutex_after_fork<T: ?Sized>(mutex: &PyThreadMutex<T>) {
124 unsafe { mutex.raw().reinit_after_fork() }
125}