PTLib  Version 2.14.3
 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: 32714 $
27  * $Author: rjongbloed $
28  * $Date: 2014-09-09 15:54:33 +1000 (Tue, 09 Sep 2014) $
29  */
30 
31 #ifndef PTLIB_CRITICALSECTION_H
32 #define PTLIB_CRITICALSECTION_H
33 
34 #include <ptlib/psync.h>
35 
36 #ifdef P_ATOMICITY_HEADER
37  #include P_ATOMICITY_HEADER
38 #endif
39 
40 
47 #ifdef _WIN32
48 
49 class PCriticalSection : public PSync
50 {
52 
53  public:
59 
64 
68 
72  PCriticalSection & operator=(const PCriticalSection &) { return *this; }
74 
79  PObject * Clone() const
80  {
81  return new PCriticalSection();
82  }
83 
86  virtual void Wait();
87  inline void Enter() { Wait(); }
88 
94  virtual PBoolean Wait(
95  const PTimeInterval & timeout // Amount of time to wait.
96  );
97 
100  virtual void Signal();
101  inline void Leave() { Signal(); }
102 
106  bool Try();
108 
109 
110 #include "msos/ptlib/critsec.h"
111 
112 };
113 
114 #endif
115 
117 
118 
120 {
121  public:
122 #if defined(_WIN32)
123  typedef long IntegerType;
124 #elif defined(P_ATOMICITY_BUILTIN)
125  typedef int IntegerType;
126 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
127  typedef __stl_atomic_t IntegerType;
128 #elif defined(SOLARIS) && !defined(__GNUC__)
129  typedef uint32_t IntegerType;
130 #elif defined(__GNUC__) && defined(P_ATOMICITY_HEADER)
131  typedef _Atomic_word IntegerType;
132 #else
133  typedef int IntegerType;
134  protected:
135  pthread_mutex_t m_mutex;
136 #endif
137 
138  protected:
140 
141  explicit PAtomicBase(IntegerType value);
142 
143  public:
145  ~PAtomicBase();
146 };
147 
148 
149 
165 {
166  public:
168 
171  explicit PAtomicInteger(
172  IntegerType value = 0
173  ) : PAtomicBase(value) { }
174 
176  __inline operator IntegerType() const { return m_value; }
177 
179  __inline PAtomicInteger & operator=(IntegerType value) { m_value = value; return *this; }
180 
182  void SetValue(
183  IntegerType value
184  ) { m_value = value; }
185 
192  __inline bool IsZero() const { return m_value == 0; }
193 
195  __inline bool operator!() const { return m_value == 0; }
196 
203 
209  IntegerType operator++(int);
210 
217 
223  IntegerType operator--(int);
224 
225 
226  friend __inline ostream & operator<<(ostream & strm, const PAtomicInteger & i)
227  {
228  return strm << i.m_value;
229  }
230 };
231 
232 
236 {
237  public:
240  explicit PAtomicBoolean(
241  bool value = false
242  ) : PAtomicBase(value ? 1 : 0) { }
243 
245  __inline operator bool() const { return m_value != 0; }
246 
248  __inline PAtomicBoolean & operator=(bool value) { m_value = value ? 1 : 0; return *this; }
249 
251  __inline bool operator!() const { return m_value == 0; }
252 
256  bool TestAndSet(
257  bool value
258  );
259 
260 
261  friend __inline ostream & operator<<(ostream & strm, const PAtomicBoolean & b)
262  {
263  return strm << (b.m_value != 0 ? "true" : "false");
264  }
265 };
266 
267 
268 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
269 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { }
271 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return InterlockedIncrement (&m_value); }
272 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return InterlockedExchangeAdd(&m_value, 1); }
273 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return InterlockedDecrement (&m_value); }
274 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return InterlockedExchangeAdd(&m_value, -1); }
275 __inline bool PAtomicBoolean::TestAndSet(bool value) { return InterlockedExchange (&m_value, value) != 0; }
276 #elif defined(P_ATOMICITY_BUILTIN)
277 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { }
278 __inline PAtomicBase::~PAtomicBase() { }
279 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return __sync_add_and_fetch(&m_value, 1); }
280 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return __sync_fetch_and_add(&m_value, 1); }
281 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return __sync_sub_and_fetch(&m_value, 1); }
282 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return __sync_fetch_and_sub(&m_value, 1); }
283 __inline bool PAtomicBoolean::TestAndSet(bool value) { return value ? __sync_fetch_and_or(&m_value, 1) : __sync_fetch_and_and(&m_value, 0); }
284 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_INCREMENT) && defined(_STLP_ATOMIC_DECREMENT)
285 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { }
286 __inline PAtomicBase::~PAtomicBase() { }
287 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return _STLP_ATOMIC_INCREMENT(&m_value); }
288 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return _STLP_ATOMIC_INCREMENT(&m_value)-1; }
289 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return _STLP_ATOMIC_DECREMENT(&m_value); }
290 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return _STLP_ATOMIC_DECREMENT(&m_value)+1; }
291 __inline bool PAtomicBoolean::TestAndSet(bool value) { return _STLP_ATOMIC_EXCHANGE (&m_value, value) != 0; }
292 #elif defined(SOLARIS) && !defined(__GNUC__)
293 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { }
294 __inline PAtomicBase::~PAtomicBase() { }
295 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return atomic_add_32_nv(&m_value, 1); }
296 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return atomic_add_32_nv(&m_value, 1)-1; }
297 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return atomic_add_32_nv(&m_value, -1); }
298 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return atomic_add_32_nv(&m_value, -1)+1; }
299 __inline bool PAtomicBoolean::TestAndSet(bool value) { return atomic_swap_32 (&m_value, value) != 0; }
300 #elif defined(P_ATOMICITY_HEADER)
301 #define EXCHANGE_AND_ADD P_ATOMICITY_NAMESPACE __exchange_and_add
302 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { }
303 __inline PAtomicBase::~PAtomicBase() { }
304 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { return EXCHANGE_AND_ADD(&m_value, 1)+1; }
305 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { return EXCHANGE_AND_ADD(&m_value, 1); }
306 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { return EXCHANGE_AND_ADD(&m_value, -1)-1; }
307 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { return EXCHANGE_AND_ADD(&m_value, -1); }
308 __inline bool PAtomicBoolean::TestAndSet(bool value) { IntegerType previous = EXCHANGE_AND_ADD(&m_value, value?1:-1); m_value = value?1:0; return previous > 0; }
309 #else
310 __inline PAtomicBase::PAtomicBase(IntegerType value) : m_value(value) { pthread_mutex_init(&m_mutex, NULL); }
311 __inline PAtomicBase::~PAtomicBase() { pthread_mutex_destroy(&m_mutex); }
312 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++() { pthread_mutex_lock(&m_mutex); int retval = ++m_value; pthread_mutex_unlock(&m_mutex); return retval; }
313 __inline PAtomicInteger::IntegerType PAtomicInteger::operator++(int) { pthread_mutex_lock(&m_mutex); int retval = m_value++; pthread_mutex_unlock(&m_mutex); return retval; }
314 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--() { pthread_mutex_lock(&m_mutex); int retval = --m_value; pthread_mutex_unlock(&m_mutex); return retval; }
315 __inline PAtomicInteger::IntegerType PAtomicInteger::operator--(int) { pthread_mutex_lock(&m_mutex); int retval = m_value--; pthread_mutex_unlock(&m_mutex); return retval; }
316 __inline bool PAtomicBoolean::TestAndSet(bool value) { pthread_mutex_lock(&m_mutex); int retval = m_value; m_value = value; pthread_mutex_unlock(&m_mutex); return retval != 0; }
317 #endif
318 
319 
320 #endif // PTLIB_CRITICALSECTION_H
321 
322 
323 // End Of File ///////////////////////////////////////////////////////////////