Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /WcsAPI/Interlocked.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide 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 sho1get 11 #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