use base::prelude::*;
use io::{Write};
use fmt::{Debug};
use cell::cell::{Cell};
use lock::{Lock, LockGuard};
use time_base::{Time};
pub struct Mutex<T>
{
lock: Lock,
data: Cell<T>,
}
impl<T> Mutex<T> {
pub const fn new(data: T) -> Mutex<T> {
Mutex {
lock: Lock::new(),
data: Cell::new(data),
}
}
fn guard<'a>(&'a self, guard: LockGuard<'a>) -> MutexGuard<'a, T> {
MutexGuard {
guard: guard,
mutex: self,
_marker: (NoSend, NoSync),
}
}
pub fn as_lock(&self) -> &Lock {
&self.lock
}
pub fn try_lock<'a>(&'a self) -> Result<MutexGuard<'a, T>> {
self.lock.try_lock().map(|g| self.guard(g))
}
pub fn lock<'a>(&'a self) -> MutexGuard<'a, T> {
self.guard(self.lock.lock())
}
pub fn try_lock_until<'a>(&'a self, time: Time) -> Result<MutexGuard<'a, T>> {
self.lock.try_lock_for(time).map(|g| self.guard(g))
}
pub fn existing_lock<'a>(&'a self, guard: LockGuard<'a>) -> MutexGuard<'a, T> {
assert!(&self.lock == guard.as_lock());
self.guard(guard)
}
pub fn data(&mut self) -> &mut T {
unsafe { &mut *self.data.ptr() }
}
}
unsafe impl<T> Sync for Mutex<T> where T: Send { }
unsafe impl<T> Send for Mutex<T> where T: Send { }
pub struct MutexGuard<'a, T: 'a> {
guard: LockGuard<'a>,
mutex: &'a Mutex<T>,
_marker: (NoSend, NoSync),
}
impl<'a, T> MutexGuard<'a, T> {
pub fn as_lock_guard(&self) -> &LockGuard<'a> {
&self.guard
}
pub fn into_lock_guard(self) -> LockGuard<'a> {
self.guard
}
pub fn as_mutex(&self) -> &'a Mutex<T> {
self.mutex
}
pub fn unlock(self) -> &'a Mutex<T> {
self.mutex
}
}
unsafe impl<'a, T> Sync for MutexGuard<'a, T> where T: Sync { }
unsafe impl<'a, T> Send for MutexGuard<'a, T> where T: Send { }
impl<'a, T> Deref for MutexGuard<'a, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.mutex.data.ptr() }
}
}
impl<'a, T> DerefMut for MutexGuard<'a, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.mutex.data.ptr() }
}
}
impl<'a, T: Debug> Debug for MutexGuard<'a, T> {
fn fmt<W: Write>(&self, w: &mut W) -> Result {
self.deref().fmt(w)
}
}