Sha256: c4ee49e1751ee0a7df1a8cbd4f8d36ea1d7355e3ac584fdb8697a94cd7a7a8f8
Contents?: true
Size: 1.65 KB
Versions: 38
Compression:
Stored size: 1.65 KB
Contents
use crate::loom::sync::atomic::AtomicBool; use std::cell::UnsafeCell; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::sync::atomic::Ordering::SeqCst; pub(crate) struct TryLock<T> { locked: AtomicBool, data: UnsafeCell<T>, } pub(crate) struct LockGuard<'a, T> { lock: &'a TryLock<T>, _p: PhantomData<std::rc::Rc<()>>, } unsafe impl<T: Send> Send for TryLock<T> {} unsafe impl<T: Send> Sync for TryLock<T> {} unsafe impl<T: Sync> Sync for LockGuard<'_, T> {} macro_rules! new { ($data:ident) => { TryLock { locked: AtomicBool::new(false), data: UnsafeCell::new($data), } }; } impl<T> TryLock<T> { #[cfg(not(loom))] /// Create a new `TryLock` pub(crate) const fn new(data: T) -> TryLock<T> { new!(data) } #[cfg(loom)] /// Create a new `TryLock` pub(crate) fn new(data: T) -> TryLock<T> { new!(data) } /// Attempt to acquire lock pub(crate) fn try_lock(&self) -> Option<LockGuard<'_, T>> { if self .locked .compare_exchange(false, true, SeqCst, SeqCst) .is_err() { return None; } Some(LockGuard { lock: self, _p: PhantomData, }) } } impl<T> Deref for LockGuard<'_, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.lock.data.get() } } } impl<T> DerefMut for LockGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.lock.data.get() } } } impl<T> Drop for LockGuard<'_, T> { fn drop(&mut self) { self.lock.locked.store(false, SeqCst); } }
Version data entries
38 entries across 38 versions & 1 rubygems