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}