aboutsummaryrefslogtreecommitdiff
path: root/src/sync.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/sync.rs')
-rw-r--r--src/sync.rs69
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,
- }
- }
}