Ice 3.7 C++11 API Reference
Loading...
Searching...
No Matches
Monitor.h
Go to the documentation of this file.
1//
2// Copyright (c) ZeroC, Inc. All rights reserved.
3//
4
5#ifndef ICE_UTIL_MONITOR_H
6#define ICE_UTIL_MONITOR_H
7
8#include <IceUtil/Config.h>
9#include <IceUtil/Lock.h>
10#include <IceUtil/Cond.h>
11
12namespace IceUtil
13{
14
15//
16// This monitor implements the Mesa monitor semantics. That is any
17// calls to notify() or notifyAll() are delayed until the monitor is
18// unlocked.
19//
20template <class T>
22{
23public:
24
27
30
31 //
32 // Note that lock/tryLock & unlock in general should not be used
33 // directly. Instead use Lock & TryLock.
34 //
35 void lock() const;
36 void unlock() const;
37 bool tryLock() const;
38
39 void wait() const;
40 bool timedWait(const Time&) const;
41 void notify();
42 void notifyAll();
43
44private:
45
46 // noncopyable
47 Monitor(const Monitor&);
48 void operator=(const Monitor&);
49
50 void notifyImpl(int) const;
51
52 mutable Cond _cond;
53 T _mutex;
54 mutable int _nnotify;
55};
56
57} // End namespace IceUtil
58
59//
60// Since this monitor implements the Mesa monitor semantics calls to
61// notify() or notifyAll() are delayed until the monitor is
62// unlocked. This can happen either due to a call to unlock(), or a
63// call to wait(). The _nnotify flag keeps track of the number of
64// pending notification calls. -1 indicates a broadcast, a positive
65// number indicates <n> calls to notify(). The _nnotify flag is reset
66// upon initial acquisition of the monitor lock (either through a call
67// to lock(), or a return from wait().
68//
69
70template <class T> inline
72 _nnotify(0)
73{
74}
75
76template <class T> inline
80
81template <class T> inline void
83{
84 _mutex.lock();
85 if(_mutex.willUnlock())
86 {
87 //
88 // On the first mutex acquisition reset the number pending
89 // notifications.
90 //
91 _nnotify = 0;
92 }
93}
94
95template <class T> inline void
97{
98 if(_mutex.willUnlock())
99 {
100 //
101 // Perform any pending notifications.
102 //
103 notifyImpl(_nnotify);
104 }
105 _mutex.unlock();
106
107/*
108 int nnotify = _nnotify;
109 if(_mutex.unlock())
110 {
111 //
112 // Perform any pending notifications.
113 //
114 notifyImpl(nnotify);
115 }
116*/
117}
118
119template <class T> inline bool
121{
122 bool result = _mutex.tryLock();
123 if(result && _mutex.willUnlock())
124 {
125 //
126 // On the first mutex acquisition reset the number pending
127 // notifications.
128 //
129 _nnotify = 0;
130 }
131 return result;
132}
133
134template <class T> inline void
136{
137 //
138 // Perform any pending notifies
139 //
140 notifyImpl(_nnotify);
141
142 //
143 // Wait for a notification
144 //
145 try
146 {
147 _cond.waitImpl(_mutex);
148 //
149 // Reset the nnotify count once wait() returns.
150 //
151 }
152 catch(...)
153 {
154 _nnotify = 0;
155 throw;
156 }
157
158 _nnotify = 0;
159}
160
161template <class T> inline bool
163{
164 //
165 // Perform any pending notifies.
166 //
167 notifyImpl(_nnotify);
168
169 bool rc;
170 //
171 // Wait for a notification.
172 //
173 try
174 {
175 rc = _cond.timedWaitImpl(_mutex, timeout);
176
177 //
178 // Reset the nnotify count once wait() returns.
179 //
180 }
181 catch(...)
182 {
183 _nnotify = 0;
184 throw;
185 }
186
187 _nnotify = 0;
188 return rc;
189}
190
191template <class T> inline void
193{
194 //
195 // Increment the _nnotify flag, unless a broadcast has already
196 // been requested.
197 //
198 if(_nnotify != -1)
199 {
200 ++_nnotify;
201 }
202}
203
204template <class T> inline void
206{
207 //
208 // -1 (indicates broadcast)
209 //
210 _nnotify = -1;
211}
212
213template <class T> inline void
214IceUtil::Monitor<T>::notifyImpl(int nnotify) const
215{
216 //
217 // Zero indicates no notifies.
218 //
219 if(nnotify != 0)
220 {
221 //
222 // -1 means notifyAll.
223 //
224 if(nnotify == -1)
225 {
226 _cond.broadcast();
227 return;
228 }
229 else
230 {
231 //
232 // Otherwise notify n times.
233 //
234 while(nnotify > 0)
235 {
236 _cond.signal();
237 --nnotify;
238 }
239 }
240 }
241}
242
243#endif
Definition Cond.h:53
Definition Lock.h:37
void wait() const
Definition Monitor.h:135
void lock() const
Definition Monitor.h:82
void notify()
Definition Monitor.h:192
TryLockT< Monitor< T > > TryLock
Definition Monitor.h:26
bool tryLock() const
Definition Monitor.h:120
void notifyAll()
Definition Monitor.h:205
bool timedWait(const Time &) const
Definition Monitor.h:162
LockT< Monitor< T > > Lock
Definition Monitor.h:25
void unlock() const
Definition Monitor.h:96
Monitor()
Definition Monitor.h:71
~Monitor()
Definition Monitor.h:77
Definition Time.h:18
Definition Lock.h:118
Definition Optional.h:1095