rustpython_common/
lock.rs1use lock_api::{
5 MappedMutexGuard, MappedRwLockReadGuard, MappedRwLockWriteGuard, Mutex, MutexGuard, RwLock,
6 RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard,
7};
8
9cfg_select! {
10 feature = "threading" => {
11 pub use detaching::{BlockingWaitHook, set_blocking_wait_hook, set_world_stopped};
12 pub use parking_lot::{RawMutex, RawRwLock, RawThreadId};
13 pub use std::sync::OnceLock as OnceCell;
14 pub use core::cell::LazyCell;
15 }
16 _ => {
17 mod cell_lock;
18 pub use cell_lock::{RawCellMutex as RawMutex, RawCellRwLock as RawRwLock, SingleThreadId as RawThreadId};
19
20 pub use core::cell::{LazyCell, OnceCell};
21 }
22}
23
24cfg_select! {
28 any(feature = "threading", feature = "std") => {
29 pub use std::sync::LazyLock;
30 }
31 _ => {
32 pub struct LazyLock<T, F = fn() -> T>(core::cell::LazyCell<T, F>);
33 unsafe impl<T, F> Sync for LazyLock<T, F> {}
38
39 impl<T, F: FnOnce() -> T> LazyLock<T, F> {
40 pub const fn new(f: F) -> Self { Self(core::cell::LazyCell::new(f)) }
41 pub fn force(this: &Self) -> &T { core::cell::LazyCell::force(&this.0) }
42 }
43
44 impl<T, F: FnOnce() -> T> core::ops::Deref for LazyLock<T, F> {
45 type Target = T;
46 fn deref(&self) -> &T { &self.0 }
47 }
48 }
49}
50
51mod detaching;
52pub use detaching::RawDetachingRwLock;
53mod immutable_mutex;
54pub use immutable_mutex::*;
55mod thread_mutex;
56pub use thread_mutex::*;
57
58pub type PyMutex<T> = Mutex<RawMutex, T>;
59pub type PyMutexGuard<'a, T> = MutexGuard<'a, RawMutex, T>;
60pub type PyMappedMutexGuard<'a, T> = MappedMutexGuard<'a, RawMutex, T>;
61pub type PyImmutableMappedMutexGuard<'a, T> = ImmutableMappedMutexGuard<'a, RawMutex, T>;
62pub type PyThreadMutex<T> = ThreadMutex<RawMutex, RawThreadId, T>;
63pub type PyThreadMutexGuard<'a, T> = ThreadMutexGuard<'a, RawMutex, RawThreadId, T>;
64pub type PyMappedThreadMutexGuard<'a, T> = MappedThreadMutexGuard<'a, RawMutex, RawThreadId, T>;
65
66pub type PyDetachingRwLock<T> = RwLock<RawDetachingRwLock, T>;
73pub type PyDetachingRwLockReadGuard<'a, T> = RwLockReadGuard<'a, RawDetachingRwLock, T>;
74pub type PyDetachingRwLockWriteGuard<'a, T> = RwLockWriteGuard<'a, RawDetachingRwLock, T>;
75pub type PyMappedDetachingRwLockReadGuard<'a, T> = MappedRwLockReadGuard<'a, RawDetachingRwLock, T>;
76pub type PyMappedDetachingRwLockWriteGuard<'a, T> =
77 MappedRwLockWriteGuard<'a, RawDetachingRwLock, T>;
78
79pub type PyRwLock<T> = RwLock<RawRwLock, T>;
80pub type PyRwLockUpgradableReadGuard<'a, T> = RwLockUpgradableReadGuard<'a, RawRwLock, T>;
81pub type PyRwLockReadGuard<'a, T> = RwLockReadGuard<'a, RawRwLock, T>;
82pub type PyMappedRwLockReadGuard<'a, T> = MappedRwLockReadGuard<'a, RawRwLock, T>;
83pub type PyRwLockWriteGuard<'a, T> = RwLockWriteGuard<'a, RawRwLock, T>;
84pub type PyMappedRwLockWriteGuard<'a, T> = MappedRwLockWriteGuard<'a, RawRwLock, T>;
85
86pub unsafe fn zero_reinit_after_fork<T>(lock: *const T) {
102 unsafe {
103 core::ptr::write_bytes(lock as *mut u8, 0, core::mem::size_of::<T>());
104 }
105}
106
107#[cfg(unix)]
114pub unsafe fn reinit_mutex_after_fork<T: ?Sized>(mutex: &PyMutex<T>) {
115 unsafe { zero_reinit_after_fork(mutex.raw()) }
116}
117
118#[cfg(unix)]
125pub unsafe fn reinit_rwlock_after_fork<T: ?Sized>(rwlock: &PyRwLock<T>) {
126 unsafe { zero_reinit_after_fork(rwlock.raw()) }
127}
128
129#[cfg(unix)]
140pub unsafe fn reinit_thread_mutex_after_fork<T: ?Sized>(mutex: &PyThreadMutex<T>) {
141 unsafe { mutex.raw().reinit_after_fork() }
142}