PTLib  Version 2.10.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
critsec.h
Go to the documentation of this file.
1 /*
2  * critsec.h
3  *
4  * Critical section mutex class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (C) 2004 Post Increment
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Post Increment
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 25356 $
27  * $Author: rjongbloed $
28  * $Date: 2011-03-17 17:37:13 -0500 (Thu, 17 Mar 2011) $
29  */
30 
31 #ifndef PTLIB_CRITICALSECTION_H
32 #define PTLIB_CRITICALSECTION_H
33 
34 #include <ptlib/psync.h>
35 
36 #if defined(SOLARIS) && !defined(__GNUC__)
37 #include <atomic.h>
38 #endif
39 
40 #if P_HAS_ATOMIC_INT
41 
42 #if defined(__GNUC__)
43 # if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
44 # include <ext/atomicity.h>
45 # else
46 # include <bits/atomicity.h>
47 # endif
48 #endif
49 
50 #if P_NEEDS_GNU_CXX_NAMESPACE
51 #define EXCHANGE_AND_ADD(v,i) __gnu_cxx::__exchange_and_add(v,i)
52 #else
53 #define EXCHANGE_AND_ADD(v,i) __exchange_and_add(v,i)
54 #endif
55 
56 #endif // P_HAS_ATOMIC_INT
57 
58 
65 #ifdef _WIN32
66 
67 class PCriticalSection : public PSync
68 {
70 
71  public:
77 
82 
86 
90  PCriticalSection & operator=(const PCriticalSection &) { return *this; }
92 
97  PObject * Clone() const
98  {
99  return new PCriticalSection();
100  }
101 
104  void Wait();
105  inline void Enter() { Wait(); }
106 
109  void Signal();
110  inline void Leave() { Signal(); }
111 
115  bool Try();
117 
118 
119 #include "msos/ptlib/critsec.h"
120 
121 };
122 
123 #endif
124 
126 
136 {
137  public:
138 #if defined(_WIN32)
139  typedef long IntegerType;
140 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
141  typedef __stl_atomic_t IntegerType;
142 #elif defined(SOLARIS) && !defined(__GNUC__)
143  typedef uint32_t IntegerType;
144 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT
145  typedef _Atomic_word IntegerType;
146 #else
147  typedef int IntegerType;
148  protected:
149  pthread_mutex_t m_mutex;
150 #endif
151 
152  protected:
154 
155  public:
158  explicit PAtomicInteger(
159  IntegerType value = 0
160  );
161 
163  ~PAtomicInteger();
164 
166  __inline operator IntegerType() const { return m_value; }
167 
169  __inline PAtomicInteger & operator=(IntegerType i) { SetValue(i); return *this; }
170 
172  __inline PAtomicInteger & operator=(const PAtomicInteger & ref) { SetValue(ref); return *this; }
173 
175  void SetValue(
176  IntegerType value
177  );
178 
186  __inline bool IsZero() const { return m_value == 0; }
187 
189  __inline bool operator!() const { return m_value != 0; }
190 
191  friend __inline ostream & operator<<(ostream & strm, const PAtomicInteger & i)
192  {
193  return strm << i.m_value;
194  }
195 
202 
208  IntegerType operator++(int);
209 
216 
222  IntegerType operator--(int);
223 };
224 
225 
226 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
227 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
229 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return InterlockedIncrement(&m_value); }
230 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return InterlockedExchangeAdd(&m_value, 1); }
231 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return InterlockedDecrement(&m_value); }
232 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return InterlockedExchangeAdd(&m_value, -1); }
233 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
234 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
235 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
236 __inline PAtomicInteger::~PAtomicInteger() { }
237 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return _STLP_ATOMIC_INCREMENT(&m_value); }
238 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return _STLP_ATOMIC_INCREMENT(&m_value)-1; }
239 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return _STLP_ATOMIC_DECREMENT(&m_value); }
240 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return _STLP_ATOMIC_DECREMENT(&m_value)+1; }
241 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
242 #elif defined(SOLARIS) && !defined(__GNUC__)
243 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
244 __inline PAtomicInteger::~PAtomicInteger() { }
245 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return atomic_add_32_nv((&m_value), 1); }
246 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return atomic_add_32_nv((&m_value), 1)-1; }
247 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return atomic_add_32_nv((&m_value), -1); }
248 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return atomic_add_32_nv((&m_value), -1)+1; }
249 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
250 #elif defined(__GNUC__) && P_HAS_ATOMIC_INT
251 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { }
252 __inline PAtomicInteger::~PAtomicInteger() { }
253 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return EXCHANGE_AND_ADD(&m_value, 1)+1; }
254 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return EXCHANGE_AND_ADD(&m_value, 1); }
255 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return EXCHANGE_AND_ADD(&m_value, -1)-1; }
256 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return EXCHANGE_AND_ADD(&m_value, -1); }
257 __inline void PAtomicInteger::SetValue(IntegerType value) { m_value = value; }
258 #else
259 __inline PAtomicInteger::PAtomicInteger(IntegerType value) : m_value(value) { pthread_mutex_init(&m_mutex, NULL); }
260 __inline PAtomicInteger::~PAtomicInteger() { pthread_mutex_destroy(&m_mutex); }
261 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { pthread_mutex_lock(&m_mutex); int retval = ++m_value; pthread_mutex_unlock(&m_mutex); return retval; }
262 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { pthread_mutex_lock(&m_mutex); int retval = m_value++; pthread_mutex_unlock(&m_mutex); return retval; }
263 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { pthread_mutex_lock(&m_mutex); int retval = --m_value; pthread_mutex_unlock(&m_mutex); return retval; }
264 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { pthread_mutex_lock(&m_mutex); int retval = m_value--; pthread_mutex_unlock(&m_mutex); return retval; }
265 __inline void PAtomicInteger::SetValue(IntegerType v) { pthread_mutex_lock(&m_mutex); m_value = v; pthread_mutex_unlock(&m_mutex); }
266 #endif
267 
268 
269 #endif // PTLIB_CRITICALSECTION_H
270 
271 
272 // End Of File ///////////////////////////////////////////////////////////////