1use alloc::sync::Arc;
2use core::{
3 fmt::{self, Debug, Formatter},
4 mem,
5 ops::{Deref, DerefMut},
6};
7
8use super::lock::{OptionGuard, OptionLock};
9use super::mutex::{Mutex, MutexGuard};
10
11pub struct OptionGuardArc<T> {
13 lock: Arc<OptionLock<T>>,
14 filled: bool,
15}
16
17impl<T> OptionGuardArc<T> {
18 #[inline]
19 pub(crate) fn new(lock: Arc<OptionLock<T>>, guard: OptionGuard<'_, T>) -> Self {
20 let result = Self {
21 lock,
22 filled: guard.is_some(),
23 };
24 mem::forget(guard);
25 result
26 }
27
28 pub fn as_ref(&self) -> Option<&T> {
30 if self.filled {
31 Some(unsafe { &*self.lock.as_mut_ptr() })
32 } else {
33 None
34 }
35 }
36
37 pub fn as_mut_ref(&mut self) -> Option<&mut T> {
39 if self.filled {
40 Some(unsafe { &mut *self.lock.as_mut_ptr() })
41 } else {
42 None
43 }
44 }
45
46 #[inline]
48 pub fn is_none(&self) -> bool {
49 !self.filled
50 }
51
52 #[inline]
54 pub fn is_some(&self) -> bool {
55 self.filled
56 }
57
58 pub fn replace(&mut self, value: T) -> Option<T> {
60 let ret = if self.filled {
61 Some(unsafe { self.lock.as_mut_ptr().read() })
62 } else {
63 self.filled = true;
64 None
65 };
66 unsafe {
67 self.lock.as_mut_ptr().write(value);
68 }
69 ret
70 }
71
72 pub fn take(&mut self) -> Option<T> {
74 if self.filled {
75 self.filled = false;
76 Some(unsafe { self.lock.as_mut_ptr().read() })
77 } else {
78 None
79 }
80 }
81}
82
83impl<T: Debug> Debug for OptionGuardArc<T> {
84 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
85 f.debug_tuple("OptionGuardArc")
86 .field(&self.as_ref())
87 .finish()
88 }
89}
90
91impl<T> Drop for OptionGuardArc<T> {
92 fn drop(&mut self) {
93 let _ = OptionGuard::new(&self.lock, self.filled);
94 }
95}
96
97unsafe impl<T: Send> Send for OptionGuardArc<T> {}
98unsafe impl<T: Sync> Sync for OptionGuardArc<T> {}
99
100pub struct MutexGuardArc<T> {
102 lock: Arc<Mutex<T>>,
103}
104
105impl<T> MutexGuardArc<T> {
106 #[inline]
107 pub(crate) fn new(lock: Arc<Mutex<T>>, guard: MutexGuard<'_, T>) -> Self {
108 let result = Self { lock };
109 mem::forget(guard);
110 result
111 }
112
113 pub fn replace(&mut self, value: T) -> T {
115 mem::replace(unsafe { &mut *self.lock.as_mut_ptr() }, value)
116 }
117}
118
119impl<T> Deref for MutexGuardArc<T> {
120 type Target = T;
121
122 fn deref(&self) -> &Self::Target {
123 unsafe { &*self.lock.as_ptr() }
124 }
125}
126
127impl<T> DerefMut for MutexGuardArc<T> {
128 fn deref_mut(&mut self) -> &mut Self::Target {
129 unsafe { &mut *self.lock.as_mut_ptr() }
130 }
131}
132
133impl<T: Debug> Debug for MutexGuardArc<T> {
134 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
135 f.debug_tuple("MutexGuardArc").field(&**self).finish()
136 }
137}
138
139impl<T> Drop for MutexGuardArc<T> {
140 fn drop(&mut self) {
141 let _ = OptionGuard::new(&self.lock.inner, true);
142 }
143}
144
145unsafe impl<T: Send> Send for MutexGuardArc<T> {}
146unsafe impl<T: Sync> Sync for MutexGuardArc<T> {}