Develop and Download Open Source Software

Browse Subversion Repository

Contents of /WcsAPI/Interlocked.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations) (download) (as text)
Wed Feb 10 18:21:00 2010 UTC (14 years, 2 months ago) by sho1get
File MIME type: text/x-chdr
File size: 7956 byte(s)


1 #pragma once
2
3 ///////////////////////////////////////////////////////////////////////////////
4
5 class CLock
6 {
7 public:
8 CLock()
9 {
10 InitializeCriticalSection(&m_cs);
11 m_lRefCnt = 0;
12 }
13
14 virtual ~CLock()
15 {
16 DeleteCriticalSection(&m_cs);
17 }
18
19 void Enter()
20 {
21 EnterCriticalSection(&m_cs);
22 m_lRefCnt++;
23 }
24
25 BOOL TryEnter()
26 {
27 BOOL fRet = TryEnterCriticalSection(&m_cs);
28 if (fRet)
29 {
30 m_lRefCnt++;
31 }
32 return fRet;
33 }
34
35 void Leave()
36 {
37 m_lRefCnt--;
38 LeaveCriticalSection(&m_cs);
39 }
40
41 BOOL IsLocked() const
42 {
43 return (m_lRefCnt > 0);
44 }
45
46 protected:
47 CRITICAL_SECTION m_cs;
48 long m_lRefCnt;
49 };
50
51
52 // Instances of this class will be accessed by multiple threads. So,
53 // all members of this class (except the constructor and destructor)
54 // must be thread-safe.
55 class CResGuard
56 {
57 public:
58 CResGuard() { m_lGrdCnt = 0; InitializeCriticalSection(&m_cs); }
59 ~CResGuard() { DeleteCriticalSection(&m_cs); }
60
61 // IsGuarded is used for debugging
62 BOOL IsGuarded() const { return (m_lGrdCnt > 0); }
63
64 public:
65 class CGuard
66 {
67 public:
68 CGuard(CResGuard& rg) : m_rg(rg) { m_rg.Guard(); };
69 ~CGuard() { m_rg.Unguard(); }
70
71 private:
72 CResGuard& m_rg;
73 };
74
75 private:
76 void Guard() { EnterCriticalSection(&m_cs); m_lGrdCnt++; }
77 void Unguard() { m_lGrdCnt--; LeaveCriticalSection(&m_cs); }
78
79 // Guard/Unguard can only be accessed by the nested CGuard class.
80 friend class CResGuard::CGuard;
81
82 private:
83 CRITICAL_SECTION m_cs;
84 long m_lGrdCnt; // # of EnterCriticalSection calls
85 };
86
87
88 ///////////////////////////////////////////////////////////////////////////////
89
90
91 // Instances of this class will be accessed by multiple threads. So,
92 // all members of this class (except the constructor and destructor)
93 // must be thread-safe.
94 template <class TYPE>
95 class CInterlockedType
96 {
97 public: // Public member functions
98 // Note: Constructors & destructors are always thread safe
99 CInterlockedType() {}
100 CInterlockedType(const TYPE& TVal) { m_TVal = TVal; }
101 virtual ~CInterlockedType() {}
102
103 // Cast operator to make writing code that uses
104 // thread-safe data type easier
105 operator TYPE() const
106 {
107 CResGuard::CGuard x(m_rg);
108 return GetVal();
109 }
110
111 protected: // Protected function to be called by derived class
112 TYPE& GetVal()
113 {
114 return m_TVal;
115 }
116
117 const TYPE& GetVal() const
118 {
119 return m_TVal;
120 }
121
122 TYPE SetVal(const TYPE& TNewVal)
123 {
124 TYPE& TVal = GetVal();
125 if (TVal != TNewVal)
126 {
127 TYPE TPrevVal = TVal;
128 TVal = TNewVal;
129 OnValChanged(TNewVal, TPrevVal);
130 }
131 return TVal;
132 }
133
134 protected: // Overridable functions
135 virtual void OnValChanged(
136 const TYPE& TNewVal, const TYPE& TPrevVal) const
137 {
138 // Nothing to do here
139 }
140
141 protected:
142 // Protected guard for use by derived class functions
143 mutable CResGuard m_rg;
144
145 private: // Private data members
146 TYPE m_TVal;
147 };
148
149 ///////////////////////////////////////////////////////////////////////////////
150
151 // Instances of this class will be accessed by multiple threads. So,
152 // all members of this class (except the constructor and destructor)
153 // must be thread-safe.
154 template <class TYPE>
155 class CInterlockedScalar : protected CInterlockedType<TYPE>
156 {
157 public:
158 CInterlockedScalar(TYPE TVal = 0) : CInterlockedType<TYPE>(TVal) {}
159 ~CInterlockedScalar() { /* Nothing to do */ }
160
161 // C++ does not allow operator cast to be inherited.
162 operator TYPE() const
163 {
164 return (CInterlockedType<TYPE>::operator TYPE());
165 }
166
167 TYPE operator=(TYPE TVal)
168 {
169 CResGuard::CGuard x(m_rg);
170 return SetVal(TVal);
171 }
172
173 TYPE operator++(int) // Postfix increment operator
174 {
175 CResGuard::CGuard x(m_rg);
176 TYPE TPrevVal = GetVal();
177 SetVal((TYPE) (TPrevVal + 1));
178 return TPrevVal; // Return value BEFORE increment
179 }
180
181 TYPE operator--(int) // Postfix decrement operator.
182 {
183 CResGuard::CGuard x(m_rg);
184 TYPE TPrevVal = GetVal();
185 SetVal((TYPE) (TPrevVal - 1));
186 return TPrevVal; // Return value BEFORE decrement
187 }
188
189 TYPE operator += (TYPE op)
190 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() + op); }
191 TYPE operator++()
192 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() + 1); }
193 TYPE operator -= (TYPE op)
194 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() - op); }
195 TYPE operator--()
196 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() - 1); }
197 TYPE operator *= (TYPE op)
198 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() * op); }
199 TYPE operator /= (TYPE op)
200 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() / op); }
201 TYPE operator %= (TYPE op)
202 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() % op); }
203 TYPE operator ^= (TYPE op)
204 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() ^ op); }
205 TYPE operator &= (TYPE op)
206 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() & op); }
207 TYPE operator |= (TYPE op)
208 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() | op); }
209 TYPE operator <<=(TYPE op)
210 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() << op); }
211 TYPE operator >>=(TYPE op)
212 { CResGuard::CGuard x(m_rg); return SetVal(GetVal() >> op); }
213 };
214
215 ///////////////////////////////////////////////////////////////////////////////
216
217 // Instances of this class will be accessed by multiple threads. So,
218 // all members of this class (except the constructor and destructor)
219 // must be thread-safe.
220 template <class TYPE>
221 class CZeroEvent : public CInterlockedScalar<TYPE>
222 {
223 public:
224 CZeroEvent(TYPE TVal = 0, BOOL fManualReset = TRUE)
225 : CInterlockedScalar<TYPE>(TVal)
226 {
227 // The event should be signaled if TVal is 0
228 m_hevtZero = CreateEvent(NULL, fManualReset, (TVal == 0), NULL);
229
230 // The event should be signaled if TVal is NOT 0
231 m_hevtNotZero = CreateEvent(NULL, fManualReset, (TVal != 0), NULL);
232 }
233
234 ~CZeroEvent()
235 {
236 CloseHandle(m_hevtZero);
237 CloseHandle(m_hevtNotZero);
238 }
239
240 // C++ does not allow operator= to be inherited.
241 TYPE operator=(TYPE x)
242 {
243 return (CInterlockedScalar<TYPE>::operator=(x));
244 }
245
246 // Return handle to event signaled when value is zero
247 operator HANDLE() const { return m_hevtZero; }
248
249 // Return handle to event signaled when value is zero
250 HANDLE GetZeroHandle() const { return m_hevtZero; }
251
252 // Return handle to event signaled when value is not zero
253 HANDLE GetNotZeroHandle() const { return m_hevtNotZero; }
254
255 // C++ does not allow operator cast to be inherited.
256 operator TYPE() const
257 {
258 return (CInterlockedScalar<TYPE>::operator TYPE());
259 }
260
261 protected:
262 void OnValChanged(const TYPE& TNewVal, const TYPE& TPrevVal) const
263 {
264 // For best performance, avoid jumping to
265 // kernel mode if we don't have to
266 if ((TNewVal == 0) && (TPrevVal != 0))
267 {
268 SetEvent(m_hevtZero);
269 ResetEvent(m_hevtNotZero);
270 }
271 if ((TNewVal != 0) && (TPrevVal == 0))
272 {
273 ResetEvent(m_hevtZero);
274 SetEvent(m_hevtNotZero);
275 }
276 }
277
278 private:
279 HANDLE m_hevtZero; // Signaled when data value is 0
280 HANDLE m_hevtNotZero; // Signaled when data value is not 0
281 };
282
283 ///////////////////////////////////////////////////////////////////////////////
284
285 template <class TYPE>
286 class CAtomic
287 {
288 public:
289 CAtomic() {}
290 CAtomic(const TYPE& TVal) { m_TVal = TVal; }
291 virtual ~CAtomic() {}
292
293 operator TYPE() const
294 {
295 CResGuard::CGuard x(m_rg);
296 return GetVal();
297 }
298
299 TYPE operator = (TYPE TVal)
300 {
301 CResGuard::CGuard x(m_rg);
302 return SetVal(TVal);
303 }
304
305 protected:
306 TYPE& GetVal()
307 {
308 return m_TVal;
309 }
310
311 const TYPE& GetVal() const
312 {
313 return m_TVal;
314 }
315
316 TYPE SetVal(const TYPE& TNewVal)
317 {
318 TYPE& TVal = GetVal();
319 TVal = TNewVal;
320 return TVal;
321 }
322
323 protected:
324 mutable CResGuard m_rg;
325
326 protected:
327 TYPE m_TVal;
328 };
329
330 //////////////////////////////// End of File //////////////////////////////////

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26