monitor/
monitor.rs

1#![allow(dead_code)]
2
3use std::sync::{Mutex, MutexGuard, Condvar, WaitTimeoutResult};
4use std::time::Duration;
5use std::ops::{Deref, DerefMut};
6
7
8pub struct Monitor<T: Sized> {
9    mutex: Mutex<T>,
10    cvar: Condvar,
11}
12
13
14
15impl<T: Sized> Monitor<T> {
16    pub fn new(val: T) -> Monitor<T> {
17        Monitor { mutex: Mutex::new(val), cvar: Condvar::new() }
18    }
19    
20    pub fn with_lock<U, F> (&self, f: F) -> U
21    where F: FnOnce(MonitorGuard<T>) -> U 
22    {
23        let g = self.mutex.lock().unwrap();
24        f(MonitorGuard::new(&self.cvar, g))
25    }
26}
27
28
29pub struct MonitorGuard<'a, T: 'a> {
30    cvar: &'a Condvar,
31    guard: Option<MutexGuard<'a, T>>
32}
33
34impl<'a, T: 'a> MonitorGuard<'a, T> {
35    pub fn new(cvar: &'a Condvar, guard: MutexGuard<'a, T>) -> MonitorGuard<'a, T> {
36        MonitorGuard { cvar: cvar, guard: Some(guard) }
37    }
38    
39    
40    pub fn wait(&mut self) {
41        let g = self.cvar.wait(self.guard.take().unwrap()).unwrap();
42        self.guard = Some(g)
43    }
44    
45    pub fn wait_timeout(&mut self, t: Duration) -> WaitTimeoutResult {
46		let (g, finished) = self.cvar.wait_timeout(self.guard.take().unwrap(), t).unwrap();
47        self.guard = Some(g);    	
48        finished
49    }
50    
51    pub fn notify_one(&self) {
52        self.cvar.notify_one();
53    }
54    
55    pub fn notify_all(&self) {
56        self.cvar.notify_all();
57    }
58}
59
60
61impl<'a, T> Deref for MonitorGuard<'a, T> {
62    type Target = T;
63
64    fn deref(&self) -> &T {
65        self.guard.as_ref().unwrap()
66    }
67}
68
69impl<'a, T> DerefMut for MonitorGuard<'a, T> {
70    fn deref_mut(&mut self) -> &mut T {
71        self.guard.as_mut().unwrap()
72    }
73}