1cfg_if::cfg_if! {
4 if #[cfg(feature = "parking_lot")] {
5 use parking_lot::Mutex as MutexInner;
6 } else if #[cfg(std)] {
7 use std::sync::Mutex as MutexInner;
8 } else {
9 use core::cell::RefCell as MutexInner;
10 }
11}
12
13pub(crate) struct Mutex<T: ?Sized> {
14 inner: MutexInner<T>,
15}
16
17impl<T: ?Sized> core::fmt::Debug for Mutex<T>
18where
19 MutexInner<T>: core::fmt::Debug,
20{
21 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22 <MutexInner<T> as core::fmt::Debug>::fmt(&self.inner, f)
23 }
24}
25
26impl<T: Default> Default for Mutex<T> {
27 fn default() -> Self {
28 Self::new(<T as Default>::default())
29 }
30}
31
32impl<T> Mutex<T> {
33 pub const fn new(value: T) -> Self {
34 Self {
35 inner: MutexInner::new(value),
36 }
37 }
38}
39
40impl<T: ?Sized> Mutex<T> {
41 pub fn lock(&self) -> impl core::ops::DerefMut<Target = T> + '_ {
42 cfg_if::cfg_if! {
43 if #[cfg(feature = "parking_lot")] {
44 self.inner.lock()
45 } else if #[cfg(std)] {
46 self.inner.lock().unwrap_or_else(std::sync::PoisonError::into_inner)
47 } else {
48 loop {
49 let Ok(lock) = self.inner.try_borrow_mut() else {
50 core::hint::spin_loop();
52 continue;
53 };
54
55 break lock;
56 }
57 }
58 }
59 }
60}