source: trunk/synergy/lib/mt/CCondVar.h@ 3232

Last change on this file since 3232 was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 4.7 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef CCONDVAR_H
16#define CCONDVAR_H
17
18#include "CMutex.h"
19#include "BasicTypes.h"
20
21class CStopwatch;
22
23//! Generic condition variable
24/*!
25This class provides functionality common to all condition variables
26but doesn't provide the actual variable storage. A condition variable
27is a multiprocessing primitive that can be waited on. Every condition
28variable has an associated mutex.
29*/
30class CCondVarBase {
31public:
32 /*!
33 \c mutex must not be NULL. All condition variables have an
34 associated mutex. The mutex needn't be unique to one condition
35 variable.
36 */
37 CCondVarBase(CMutex* mutex);
38 ~CCondVarBase();
39
40 //! @name manipulators
41 //@{
42
43 //! Lock the condition variable's mutex
44 /*!
45 Lock the condition variable's mutex. The condition variable should
46 be locked before reading or writing it. It must be locked for a
47 call to wait(). Locks are not recursive; locking a locked mutex
48 will deadlock the thread.
49 */
50 void lock() const;
51
52 //! Unlock the condition variable's mutex
53 void unlock() const;
54
55 //! Signal the condition variable
56 /*!
57 Wake up one waiting thread, if there are any. Which thread gets
58 woken is undefined.
59 */
60 void signal();
61
62 //! Signal the condition variable
63 /*!
64 Wake up all waiting threads, if any.
65 */
66 void broadcast();
67
68 //@}
69 //! @name accessors
70 //@{
71
72 //! Wait on the condition variable
73 /*!
74 Wait on the condition variable. If \c timeout < 0 then wait until
75 signalled, otherwise up to \c timeout seconds or until signalled,
76 whichever comes first. Returns true if the object was signalled
77 during the wait, false otherwise.
78
79 The proper way to wait for a condition is:
80 \code
81 cv.lock();
82 while (cv-expr) {
83 cv.wait();
84 }
85 cv.unlock();
86 \endcode
87 where \c cv-expr involves the value of \c cv and is false when the
88 condition is satisfied.
89
90 (cancellation point)
91 */
92 bool wait(double timeout = -1.0) const;
93
94 //! Wait on the condition variable
95 /*!
96 Same as \c wait(double) but use \c timer to compare against \timeout.
97 Since clients normally wait on condition variables in a loop, clients
98 can use this to avoid recalculating \c timeout on each iteration.
99 Passing a stopwatch with a negative \c timeout is pointless (it will
100 never time out) but permitted.
101
102 (cancellation point)
103 */
104 bool wait(CStopwatch& timer, double timeout) const;
105
106 //! Get the mutex
107 /*!
108 Get the mutex passed to the c'tor.
109 */
110 CMutex* getMutex() const;
111
112 //@}
113
114private:
115 // not implemented
116 CCondVarBase(const CCondVarBase&);
117 CCondVarBase& operator=(const CCondVarBase&);
118
119private:
120 CMutex* m_mutex;
121 CArchCond m_cond;
122};
123
124//! Condition variable
125/*!
126A condition variable with storage for type \c T.
127*/
128template <class T>
129class CCondVar : public CCondVarBase {
130public:
131 //! Initialize using \c value
132 CCondVar(CMutex* mutex, const T& value);
133 //! Initialize using another condition variable's value
134 CCondVar(const CCondVar&);
135 ~CCondVar();
136
137 //! @name manipulators
138 //@{
139
140 //! Assigns the value of \c cv to this
141 /*!
142 Set the variable's value. The condition variable should be locked
143 before calling this method.
144 */
145 CCondVar& operator=(const CCondVar& cv);
146
147 //! Assigns \c value to this
148 /*!
149 Set the variable's value. The condition variable should be locked
150 before calling this method.
151 */
152 CCondVar& operator=(const T& v);
153
154 //@}
155 //! @name accessors
156 //@{
157
158 //! Get the variable's value
159 /*!
160 Get the variable's value. The condition variable should be locked
161 before calling this method.
162 */
163 operator const volatile T&() const;
164
165 //@}
166
167private:
168 volatile T m_data;
169};
170
171template <class T>
172inline
173CCondVar<T>::CCondVar(
174 CMutex* mutex,
175 const T& data) :
176 CCondVarBase(mutex),
177 m_data(data)
178{
179 // do nothing
180}
181
182template <class T>
183inline
184CCondVar<T>::CCondVar(
185 const CCondVar& cv) :
186 CCondVarBase(cv.getMutex()),
187 m_data(cv.m_data)
188{
189 // do nothing
190}
191
192template <class T>
193inline
194CCondVar<T>::~CCondVar()
195{
196 // do nothing
197}
198
199template <class T>
200inline
201CCondVar<T>&
202CCondVar<T>::operator=(const CCondVar<T>& cv)
203{
204 m_data = cv.m_data;
205 return *this;
206}
207
208template <class T>
209inline
210CCondVar<T>&
211CCondVar<T>::operator=(const T& data)
212{
213 m_data = data;
214 return *this;
215}
216
217template <class T>
218inline
219CCondVar<T>::operator const volatile T&() const
220{
221 return m_data;
222}
223
224#endif
Note: See TracBrowser for help on using the repository browser.