1use std::sync::{Condvar, LockResult};
8use std::ops::{Deref, DerefMut};
9use std::fmt;
10
11use poison;
12use {SharedMutex, SharedMutexReadGuard, SharedMutexWriteGuard};
13
14pub struct Monitor<T: ?Sized> {
19 cond: Condvar,
20 mutex: SharedMutex<T>
21}
22
23pub struct MonitorReadGuard<'mutex, T: ?Sized + 'mutex> {
25 guard: SharedMutexReadGuard<'mutex, T>,
26 cond: &'mutex Condvar
27}
28
29pub struct MonitorWriteGuard<'mutex, T: ?Sized + 'mutex> {
31 guard: SharedMutexWriteGuard<'mutex, T>,
32 cond: &'mutex Condvar
33}
34
35impl<T> Monitor<T> {
36 pub fn new(val: T) -> Monitor<T> {
38 Monitor {
39 mutex: SharedMutex::new(val),
40 cond: Condvar::new()
41 }
42 }
43}
44
45impl<T: ?Sized> Monitor<T> {
46 pub fn read(&self) -> LockResult<MonitorReadGuard<T>> {
48 poison::map_result(self.mutex.read(), |guard| {
49 MonitorReadGuard {
50 guard: guard,
51 cond: &self.cond
52 }
53 })
54 }
55
56 pub fn write(&self) -> LockResult<MonitorWriteGuard<T>> {
58 poison::map_result(self.mutex.write(), |guard| {
59 MonitorWriteGuard {
60 guard: guard,
61 cond: &self.cond
62 }
63 })
64 }
65
66 #[inline]
72 pub fn notify_one(&self) { self.cond.notify_one() }
73
74 #[inline]
80 pub fn notify_all(&self) { self.cond.notify_all() }
81
82 #[inline]
84 pub fn cond(&self) -> &Condvar { &self.cond }
85}
86
87impl<'mutex, T: ?Sized> MonitorReadGuard<'mutex, T> {
88 pub fn wait_for_read(self) -> LockResult<Self> {
90 let (guard, cond) = (self.guard, self.cond);
91 poison::map_result(guard.wait_for_read(cond), |guard| {
92 MonitorReadGuard {
93 guard: guard,
94 cond: cond
95 }
96 })
97 }
98
99 pub fn wait_for_write(self) -> LockResult<MonitorWriteGuard<'mutex, T>> {
101 let (guard, cond) = (self.guard, self.cond);
102 poison::map_result(guard.wait_for_write(cond), |guard| {
103 MonitorWriteGuard {
104 guard: guard,
105 cond: cond
106 }
107 })
108 }
109
110 pub fn notify_one(&self) { self.cond.notify_one() }
112
113 pub fn notify_all(&self) { self.cond.notify_all() }
115}
116
117impl<'mutex, T: ?Sized> MonitorWriteGuard<'mutex, T> {
118 pub fn wait_for_read(self) -> LockResult<MonitorReadGuard<'mutex, T>> {
120 let (guard, cond) = (self.guard, self.cond);
121 poison::map_result(guard.wait_for_read(cond), |guard| {
122 MonitorReadGuard {
123 guard: guard,
124 cond: cond
125 }
126 })
127 }
128
129 pub fn wait_for_write(self) -> LockResult<Self> {
131 let (guard, cond) = (self.guard, self.cond);
132 poison::map_result(guard.wait_for_write(cond), |guard| {
133 MonitorWriteGuard {
134 guard: guard,
135 cond: cond
136 }
137 })
138 }
139
140 pub fn notify_one(&self) { self.cond.notify_one() }
142
143 pub fn notify_all(&self) { self.cond.notify_all() }
145}
146
147impl<'mutex, T: ?Sized> Deref for MonitorReadGuard<'mutex, T> {
148 type Target = SharedMutexReadGuard<'mutex, T>;
149
150 fn deref(&self) -> &Self::Target { &self.guard }
151}
152
153impl<'mutex, T: ?Sized> Deref for MonitorWriteGuard<'mutex, T> {
154 type Target = SharedMutexWriteGuard<'mutex, T>;
155
156 fn deref(&self) -> &Self::Target { &self.guard }
157}
158
159impl<'mutex, T: ?Sized> DerefMut for MonitorWriteGuard<'mutex, T> {
160 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.guard }
161}
162
163impl<'mutex, T: ?Sized> Into<SharedMutexWriteGuard<'mutex, T>> for MonitorWriteGuard<'mutex, T> {
164 fn into(self) -> SharedMutexWriteGuard<'mutex, T> { self.guard }
165}
166
167impl<'mutex, T: ?Sized> Into<SharedMutexReadGuard<'mutex, T>> for MonitorReadGuard<'mutex, T> {
168 fn into(self) -> SharedMutexReadGuard<'mutex, T> { self.guard }
169}
170
171impl<T: ?Sized> AsRef<SharedMutex<T>> for Monitor<T> {
172 fn as_ref(&self) -> &SharedMutex<T> { &self.mutex }
173}
174
175impl<T: ?Sized> AsMut<SharedMutex<T>> for Monitor<T> {
176 fn as_mut(&mut self) -> &mut SharedMutex<T> { &mut self.mutex }
177}
178
179impl<T> Into<SharedMutex<T>> for Monitor<T> {
180 fn into(self) -> SharedMutex<T> { self.mutex }
181}
182
183impl<T: ?Sized + fmt::Debug> fmt::Debug for Monitor<T> {
184 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
185 f.debug_struct("Monitor")
186 .field("mutex", &&self.mutex)
187 .finish()
188 }
189}
190
191impl<'mutex, T: ?Sized + fmt::Debug> fmt::Debug for MonitorReadGuard<'mutex, T> {
192 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
193 f.debug_struct("MonitorReadGuard")
194 .field("data", &self.guard)
195 .finish()
196 }
197}
198
199impl<'mutex, T: ?Sized + fmt::Debug> fmt::Debug for MonitorWriteGuard<'mutex, T> {
200 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
201 f.debug_struct("MonitorWriteGuard")
202 .field("data", &self.guard)
203 .finish()
204 }
205}
206