1#![no_std]
2
3use core::cell::UnsafeCell;
4use core::fmt;
5use core::marker::PhantomData;
6use core::ops::Deref;
7use core::ops::DerefMut;
8use core::sync::atomic::AtomicBool;
9use core::sync::atomic::Ordering;
10
11pub struct SimpleLock<T: ?Sized> {
18 locked: AtomicBool,
19 value: UnsafeCell<T>,
20}
21
22unsafe impl<T: ?Sized + Send> Send for SimpleLock<T> {}
23unsafe impl<T: ?Sized + Send> Sync for SimpleLock<T> {}
24
25impl<T> SimpleLock<T> {
26 pub fn new(value: T) -> SimpleLock<T> {
28 SimpleLock {
29 locked: AtomicBool::new(false),
30 value: UnsafeCell::new(value),
31 }
32 }
33}
34
35impl<T: ?Sized + Default> Default for SimpleLock<T> {
36 fn default() -> SimpleLock<T> {
37 SimpleLock::new(T::default())
38 }
39}
40
41impl<T: ?Sized> SimpleLock<T> {
42 pub fn try_lock(&self) -> Option<SimpleLockGuard<T>> {
44 if self.locked.swap(true, Ordering::Acquire) {
45 None
46 } else {
47 Some(SimpleLockGuard {
48 parent: self,
49 _marker: PhantomData,
50 })
51 }
52 }
53
54 pub fn is_locked(&self) -> bool {
56 self.locked.load(Ordering::Relaxed)
57 }
58}
59
60impl<T> From<T> for SimpleLock<T> {
61 fn from(t: T) -> Self {
62 SimpleLock::new(t)
63 }
64}
65
66impl<T: ?Sized + fmt::Debug> fmt::Debug for SimpleLock<T> {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 match self.try_lock() {
69 Some(guard) => f.debug_tuple("SimpleLock").field(&&*guard).finish(),
70 None => f.write_str("SimpleLock(<locked>)"),
71 }
72 }
73}
74
75pub struct SimpleLockGuard<'a, T: 'a + ?Sized> {
79 parent: &'a SimpleLock<T>,
80
81 _marker: PhantomData<*mut ()>,
83}
84
85unsafe impl<T: ?Sized + Sync> Sync for SimpleLockGuard<'_, T> {}
86
87impl<T: ?Sized> Drop for SimpleLockGuard<'_, T> {
88 fn drop(&mut self) {
89 self.parent.locked.store(false, Ordering::Release);
90 }
91}
92
93impl<T: ?Sized> Deref for SimpleLockGuard<'_, T> {
94 type Target = T;
95
96 fn deref(&self) -> &Self::Target {
97 unsafe { &*self.parent.value.get() }
98 }
99}
100
101impl<T: ?Sized> DerefMut for SimpleLockGuard<'_, T> {
102 fn deref_mut(&mut self) -> &mut Self::Target {
103 unsafe { &mut *self.parent.value.get() }
104 }
105}
106
107impl<T: ?Sized + fmt::Debug> fmt::Debug for SimpleLockGuard<'_, T> {
108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109 fmt::Debug::fmt(&**self, f)
110 }
111}
112
113impl<T: ?Sized + fmt::Display> fmt::Display for SimpleLockGuard<'_, T> {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 (**self).fmt(f)
116 }
117}