diff options
Diffstat (limited to 'src/sync.rs')
-rw-r--r-- | src/sync.rs | 69 |
1 files changed, 11 insertions, 58 deletions
diff --git a/src/sync.rs b/src/sync.rs index e341d78e..e314b7e8 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -14,81 +14,34 @@ //! Synchronization types //! -//! Most importantly, a priority mutex is included -use std::ops::{Deref, DerefMut}; - +//! Most importantly, a fair mutex is included use parking_lot::{Mutex, MutexGuard}; -/// A priority mutex -/// -/// A triple locking strategy is used where low priority locks must go through an additional mutex -/// to access the data. The gist is -/// -/// Low priority: lock low, lock next, lock data, unlock next, {do work}, unlock data, unlock low -/// High priority: lock next, lock data, unlock next, {do work}, unlock data +/// A fair mutex /// -/// By keeping the low lock active while working on data, a high priority consumer has immediate -/// access to the next mutex. -pub struct PriorityMutex<T> { +/// Uses an extra lock to ensure that if one thread is waiting that it will get +/// the lock before a single thread can re-lock it. +pub struct FairMutex<T> { /// Data data: Mutex<T>, /// Next-to-access next: Mutex<()>, - /// Low-priority access - low: Mutex<()>, -} - -/// Mutex guard for low priority locks -pub struct LowPriorityMutexGuard<'a, T: 'a> { - data: MutexGuard<'a, T>, - _low: MutexGuard<'a, ()>, } -impl<'a, T> Deref for LowPriorityMutexGuard<'a, T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - self.data.deref() - } -} - -impl<'a, T> DerefMut for LowPriorityMutexGuard<'a, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - self.data.deref_mut() - } -} - -impl<T> PriorityMutex<T> { - /// Create a new priority mutex - pub fn new(data: T) -> PriorityMutex<T> { - PriorityMutex { +impl<T> FairMutex<T> { + /// Create a new fair mutex + pub fn new(data: T) -> FairMutex<T> { + FairMutex { data: Mutex::new(data), next: Mutex::new(()), - low: Mutex::new(()), } } - /// Lock the mutex with high priority - pub fn lock_high(&self) -> MutexGuard<T> { + /// Lock the mutex + pub fn lock(&self) -> MutexGuard<T> { // Must bind to a temporary or the lock will be freed before going // into data.lock() let _next = self.next.lock(); self.data.lock() } - - /// Lock the mutex with low priority - pub fn lock_low(&self) -> LowPriorityMutexGuard<T> { - let low = self.low.lock(); - // Must bind to a temporary or the lock will be freed before going - // into data.lock() - let _next = self.next.lock(); - let data = self.data.lock(); - - LowPriorityMutexGuard { - data: data, - _low: low, - } - } } |