Skip to main content

pyo3/platform/
sync.rs

1use crate::sealed;
2use crate::sync::OnceExt;
3
4// TODO replace with cfg_select when MSRV >= 1.95.0
5
6#[cfg(wip_feature_std)]
7#[allow(clippy::disallowed_types)]
8type OnceInner = std::sync::Once;
9
10#[cfg(all(not(wip_feature_std), feature = "parking_lot"))]
11type OnceInner = parking_lot::Once;
12
13#[cfg(all(not(wip_feature_std), not(feature = "parking_lot")))]
14compile_error!("Please enable at least one of the following features: std, parking_lot");
15
16pub struct Once(OnceInner);
17
18impl Default for Once {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl Once {
25    /// Creates a new `Once` value.
26    #[inline(always)]
27    #[must_use]
28    pub const fn new() -> Once {
29        Once(OnceInner::new())
30    }
31
32    #[inline]
33    pub fn call_once(&self, f: impl FnOnce()) {
34        self.0.call_once(f);
35    }
36
37    #[inline]
38    pub fn call_once_force(&self, f: impl FnOnce()) {
39        self.0.call_once_force(move |_| f());
40    }
41
42    #[inline(always)]
43    pub fn is_completed(&self) -> bool {
44        cfg_select! {
45            wip_feature_std => self.0.is_completed(),
46            feature = "parking_lot" => matches!(self.0.state(), parking_lot::OnceState::Done),
47            _ => compile_error!("Please enable at least one of the following features: std, parking_lot"),
48        }
49    }
50}
51
52impl sealed::Sealed for Once {}
53impl OnceExt for Once {
54    type OnceState = ();
55
56    fn call_once_py_attached(&self, py: crate::prelude::Python<'_>, f: impl FnOnce()) {
57        self.0.call_once_force_py_attached(py, move |_| f());
58    }
59
60    fn call_once_force_py_attached(
61        &self,
62        py: crate::prelude::Python<'_>,
63        f: impl FnOnce(&Self::OnceState),
64    ) {
65        self.0.call_once_force_py_attached(py, |_| f(&()));
66    }
67}
68
69pub mod non_poison {
70    // TODO replace with cfg_select when MSRV >= 1.95.0
71    #[cfg(wip_feature_std)]
72    pub use std::sync::MutexGuard;
73
74    #[cfg(all(not(wip_feature_std), feature = "parking_lot"))]
75    pub use parking_lot::{Mutex, MutexGuard};
76
77    #[cfg(all(not(wip_feature_std), not(feature = "parking_lot")))]
78    compile_error!("Please enable at least one of the following features: std, parking_lot");
79
80    #[cfg(wip_feature_std)]
81    #[derive(Default, Debug)]
82    pub struct Mutex<T: ?Sized> {
83        #[allow(clippy::disallowed_types)]
84        inner: std::sync::Mutex<T>,
85    }
86
87    #[cfg(wip_feature_std)]
88    impl<T> Mutex<T> {
89        #[inline(always)]
90        pub const fn new(t: T) -> Mutex<T> {
91            Mutex {
92                #[allow(clippy::disallowed_types)]
93                inner: std::sync::Mutex::new(t),
94            }
95        }
96
97        pub fn into_inner(self) -> T {
98            self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
99        }
100    }
101
102    #[cfg(wip_feature_std)]
103    impl<T: ?Sized> Mutex<T> {
104        #[inline(always)]
105        pub fn lock(&self) -> std::sync::MutexGuard<'_, T> {
106            self.inner.lock().unwrap_or_else(|e| e.into_inner())
107        }
108
109        // TODO try_lock
110    }
111
112    #[cfg(wip_feature_std)]
113    impl<T> From<T> for Mutex<T> {
114        #[inline(always)]
115        fn from(t: T) -> Self {
116            Mutex {
117                #[allow(clippy::disallowed_types)]
118                inner: std::sync::Mutex::new(t),
119            }
120        }
121    }
122
123    #[cfg(wip_feature_std)]
124    impl<T> crate::sealed::Sealed for Mutex<T> {}
125
126    #[cfg(wip_feature_std)]
127    impl<T> crate::sync::MutexExt<T> for Mutex<T> {
128        type LockResult<'a>
129            = MutexGuard<'a, T>
130        where
131            T: 'a;
132
133        fn lock_py_attached(&self, py: crate::prelude::Python<'_>) -> Self::LockResult<'_> {
134            self.inner
135                .lock_py_attached(py)
136                .unwrap_or_else(|e| e.into_inner())
137        }
138    }
139}
⚠️ Internal Docs ⚠️ Not Public API 👉 Official Docs Here