critsec.h

Go to the documentation of this file.
00001 /*
00002  * critsec.h
00003  *
00004  * Critical section mutex class.
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (C) 2004 Post Increment
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Post Increment
00023  *
00024  * Contributor(s): ______________________________________.
00025  *
00026  * $Log: critsec.h,v $
00027  * Revision 1.20  2007/09/05 11:09:09  csoutheren
00028  * Removed misleading and incorrect code from Linux implementation of
00029  * PCriticalSection. Apologies to Hannes Friederich :(
00030  *
00031  * Revision 1.19  2006/09/22 00:32:21  csoutheren
00032  * Forced PAtomicInteger::operator= to be private in all compile paths
00033  *
00034  * Revision 1.18  2006/08/07 06:41:16  csoutheren
00035  * Add PCriticalSection::Clone
00036  *
00037  * Revision 1.17  2006/03/20 00:24:56  csoutheren
00038  * Applied patch #1446482
00039  * Thanks to Adam Butcher
00040  *
00041  * Revision 1.16  2006/01/18 07:17:59  csoutheren
00042  * Added explicit copy constructor for PCriticalSection on Windows
00043  *
00044  * Revision 1.15  2005/11/30 12:47:37  csoutheren
00045  * Removed tabs, reformatted some code, and changed tags for Doxygen
00046  *
00047  * Revision 1.14  2005/11/25 03:43:47  csoutheren
00048  * Fixed function argument comments to be compatible with Doxygen
00049  *
00050  * Revision 1.13  2005/11/14 22:29:13  csoutheren
00051  * Reverted Wait and Signal to non-const - there is no way we can guarantee that all
00052  * descendant classes everywhere will be changed over, so we have to keep the
00053  * original  API
00054  *
00055  * Revision 1.12  2005/11/08 10:44:37  dsandras
00056  * Fixed deadlock with code using the old API.
00057  *
00058  * Revision 1.11  2005/11/04 07:20:30  csoutheren
00059  * Provide backwards compatibility functions and typedefs
00060  *
00061  * Revision 1.10  2005/11/04 06:34:20  csoutheren
00062  * Added new class PSync as abstract base class for all mutex/sempahore classes
00063  * Changed PCriticalSection to use Wait/Signal rather than Enter/Leave
00064  * Changed Wait/Signal to be const member functions
00065  * Renamed PMutex to PTimedMutex and made PMutex synonym for PCriticalSection.
00066  * This allows use of very efficient mutex primitives in 99% of cases where timed waits
00067  * are not needed
00068  *
00069  * Revision 1.9  2004/05/16 23:31:07  csoutheren
00070  * Updated API documentation
00071  *
00072  * Revision 1.8  2004/05/12 04:36:13  csoutheren
00073  * Fixed problems with using sem_wait and friends on systems that do not
00074  * support atomic integers
00075  *
00076  * Revision 1.7  2004/04/21 11:22:56  csoutheren
00077  * Modified to work with gcc 3.4.0
00078  *
00079  * Revision 1.6  2004/04/14 06:58:00  csoutheren
00080  * Fixed PAtomicInteger and PSmartPointer to use real atomic operations
00081  *
00082  * Revision 1.5  2004/04/12 03:35:26  csoutheren
00083  * Fixed problems with non-recursuve mutexes and critical sections on
00084  * older compilers and libc
00085  *
00086  * Revision 1.4  2004/04/12 00:58:45  csoutheren
00087  * Fixed PAtomicInteger on Linux, and modified PMutex to use it
00088  *
00089  * Revision 1.3  2004/04/12 00:36:04  csoutheren
00090  * Added new class PAtomicInteger and added Windows implementation
00091  *
00092  * Revision 1.2  2004/04/11 03:20:41  csoutheren
00093  * Added Unix implementation of PCriticalSection
00094  *
00095  * Revision 1.1  2004/04/11 02:55:17  csoutheren
00096  * Added PCriticalSection for Windows
00097  * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
00098  *
00099  */
00100 
00101 #ifndef _PCRITICALSECTION
00102 #define _PCRITICALSECTION
00103 
00104 #include <ptlib/psync.h>
00105 
00106 #if P_HAS_ATOMIC_INT
00107 #if P_NEEDS_GNU_CXX_NAMESPACE
00108 #define EXCHANGE_AND_ADD(v,i)   __gnu_cxx::__exchange_and_add(v,i)
00109 #else
00110 #define EXCHANGE_AND_ADD(v,i)   __exchange_and_add(v,i)
00111 #endif
00112 #endif
00113 
00120 #ifdef _WIN32
00121 
00122 class PCriticalSection : public PSync
00123 {
00124   PCLASSINFO(PCriticalSection, PSync);
00125 
00126   public:
00131     PCriticalSection();
00132     PCriticalSection(const PCriticalSection &);
00133 
00136     ~PCriticalSection();
00138 
00143     void Wait();
00144     inline void Enter()
00145     { Wait(); }
00146 
00149     void Signal();
00150     inline void Leave()
00151     { Signal(); }
00152 
00155     PObject * Clone() const
00156     { return new PCriticalSection(); }
00157 
00159 
00160   private:
00161     PCriticalSection & operator=(const PCriticalSection &) { return *this; }
00162 
00163 #include "msos/ptlib/critsec.h"
00164 
00165 };
00166 
00167 #endif
00168 
00169 typedef PWaitAndSignal PEnterAndLeave;
00170 
00179 class PAtomicInteger 
00180 {
00181 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
00182     public:
00185       inline PAtomicInteger(
00186         long v = 0                     
00187       )
00188         : value(v) { }
00189 
00197       BOOL IsZero() const                 { return value == 0; }
00198 
00204       inline long operator++()            { return InterlockedIncrement(&value); }
00205 
00211       inline long operator--()            { return InterlockedDecrement(&value); }
00212 
00216       inline operator long () const       { return value; }
00217 
00221       inline void SetValue(
00222         long v                          
00223       )
00224       { value = v; }
00225     protected:
00226       long value;
00227 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_EXCHANGE)
00228     public:
00229       inline PAtomicInteger(__stl_atomic_t v = 0)
00230         : value(v) { }
00231       BOOL IsZero() const                { return value == 0; }
00232       inline int operator++()            { return _STLP_ATOMIC_INCREMENT(&value); }
00233       inline int unsigned operator--()   { return _STLP_ATOMIC_DECREMENT(&value); }
00234       inline operator int () const       { return value; }
00235       inline void SetValue(int v)        { value = v; }
00236     protected:
00237       __stl_atomic_t value;
00238 #elif !defined(_STLP_INTERNAL_THREADS_H) && P_HAS_ATOMIC_INT
00239     public:
00240       inline PAtomicInteger(int v = 0)
00241         : value(v) { }
00242       BOOL IsZero() const                { return value == 0; }
00243       inline int operator++()            { return EXCHANGE_AND_ADD(&value, 1) + 1; }
00244       inline int unsigned operator--()   { return EXCHANGE_AND_ADD(&value, -1) - 1; }
00245       inline operator int () const       { return value; }
00246       inline void SetValue(int v)        { value = v; }
00247     protected:
00248       _Atomic_word value;
00249 #else 
00250     protected:
00251       PCriticalSection critSec;
00252     public:
00253       inline PAtomicInteger(int v = 0)
00254         : value(v) { }
00255       BOOL IsZero() const                { return value == 0; }
00256       inline int operator++()            { PWaitAndSignal m(critSec); value++; return value;}
00257       inline int operator--()            { PWaitAndSignal m(critSec); value--; return value;}
00258       inline operator int () const       { return value; }
00259       inline void SetValue(int v)        { value = v; }
00260     protected:
00261       int value;
00262 #endif
00263     private:
00264       PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; }
00265 };
00266 
00267 #endif
00268 
00269 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1