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.15.2.1  2006/01/27 03:43:24  csoutheren
00028  * Backported changes to CVS head into Phobos
00029  *
00030  * Revision 1.16  2006/01/18 07:17:59  csoutheren
00031  * Added explicit copy constructor for PCriticalSection on Windows
00032  *
00033  * Revision 1.15  2005/11/30 12:47:37  csoutheren
00034  * Removed tabs, reformatted some code, and changed tags for Doxygen
00035  *
00036  * Revision 1.14  2005/11/25 03:43:47  csoutheren
00037  * Fixed function argument comments to be compatible with Doxygen
00038  *
00039  * Revision 1.13  2005/11/14 22:29:13  csoutheren
00040  * Reverted Wait and Signal to non-const - there is no way we can guarantee that all
00041  * descendant classes everywhere will be changed over, so we have to keep the
00042  * original  API
00043  *
00044  * Revision 1.12  2005/11/08 10:44:37  dsandras
00045  * Fixed deadlock with code using the old API.
00046  *
00047  * Revision 1.11  2005/11/04 07:20:30  csoutheren
00048  * Provide backwards compatibility functions and typedefs
00049  *
00050  * Revision 1.10  2005/11/04 06:34:20  csoutheren
00051  * Added new class PSync as abstract base class for all mutex/sempahore classes
00052  * Changed PCriticalSection to use Wait/Signal rather than Enter/Leave
00053  * Changed Wait/Signal to be const member functions
00054  * Renamed PMutex to PTimedMutex and made PMutex synonym for PCriticalSection.
00055  * This allows use of very efficient mutex primitives in 99% of cases where timed waits
00056  * are not needed
00057  *
00058  * Revision 1.9  2004/05/16 23:31:07  csoutheren
00059  * Updated API documentation
00060  *
00061  * Revision 1.8  2004/05/12 04:36:13  csoutheren
00062  * Fixed problems with using sem_wait and friends on systems that do not
00063  * support atomic integers
00064  *
00065  * Revision 1.7  2004/04/21 11:22:56  csoutheren
00066  * Modified to work with gcc 3.4.0
00067  *
00068  * Revision 1.6  2004/04/14 06:58:00  csoutheren
00069  * Fixed PAtomicInteger and PSmartPointer to use real atomic operations
00070  *
00071  * Revision 1.5  2004/04/12 03:35:26  csoutheren
00072  * Fixed problems with non-recursuve mutexes and critical sections on
00073  * older compilers and libc
00074  *
00075  * Revision 1.4  2004/04/12 00:58:45  csoutheren
00076  * Fixed PAtomicInteger on Linux, and modified PMutex to use it
00077  *
00078  * Revision 1.3  2004/04/12 00:36:04  csoutheren
00079  * Added new class PAtomicInteger and added Windows implementation
00080  *
00081  * Revision 1.2  2004/04/11 03:20:41  csoutheren
00082  * Added Unix implementation of PCriticalSection
00083  *
00084  * Revision 1.1  2004/04/11 02:55:17  csoutheren
00085  * Added PCriticalSection for Windows
00086  * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
00087  *
00088  */
00089 
00090 #ifndef _PCRITICALSECTION
00091 #define _PCRITICALSECTION
00092 
00093 #include <ptlib/psync.h>
00094 
00095 #if P_HAS_ATOMIC_INT
00096 #if P_NEEDS_GNU_CXX_NAMESPACE
00097 #define EXCHANGE_AND_ADD(v,i)   __gnu_cxx::__exchange_and_add(v,i)
00098 #else
00099 #define EXCHANGE_AND_ADD(v,i)   __exchange_and_add(v,i)
00100 #endif
00101 #endif
00102 
00109 class PCriticalSection : public PSync
00110 {
00111   PCLASSINFO(PCriticalSection, PSync);
00112 
00113   public:
00118     PCriticalSection();
00119     PCriticalSection(const PCriticalSection &);
00120 
00123     ~PCriticalSection();
00125 
00130     void Wait();
00131     inline void Enter()
00132     { Wait(); }
00133 
00136     void Signal();
00137     inline void Leave()
00138     { Signal(); }
00139 
00141 
00142   private:
00143     PCriticalSection & operator=(const PCriticalSection &) { return *this; }
00144 
00145 // Include platform dependent part of class
00146 #ifdef _WIN32
00147 #include "msos/ptlib/critsec.h"
00148 #else
00149 #include "unix/ptlib/critsec.h"
00150 #endif
00151 };
00152 
00153 typedef PWaitAndSignal PEnterAndLeave;
00154 
00163 class PAtomicInteger 
00164 {
00165 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
00166     public:
00169       inline PAtomicInteger(
00170         long v = 0                     
00171       )
00172         : value(v) { }
00173 
00181       BOOL IsZero() const                 { return value == 0; }
00182 
00188       inline long operator++()            { return InterlockedIncrement(&value); }
00189 
00195       inline long operator--()            { return InterlockedDecrement(&value); }
00196 
00200       inline operator long () const       { return value; }
00201 
00205       inline void SetValue(
00206         long v                          
00207       )
00208       { value = v; }
00209     protected:
00210       long value;
00211 #elif P_HAS_ATOMIC_INT
00212     public:
00213       inline PAtomicInteger(int v = 0)
00214         : value(v) { }
00215       BOOL IsZero() const                { return value == 0; }
00216       inline int operator++()            { return EXCHANGE_AND_ADD(&value, 1) + 1; }
00217       inline int unsigned operator--()   { return EXCHANGE_AND_ADD(&value, -1) - 1; }
00218       inline operator int () const       { return value; }
00219       inline void SetValue(int v)        { value = v; }
00220     protected:
00221       _Atomic_word value;
00222 #else 
00223     protected:
00224       PCriticalSection critSec;
00225     public:
00226       inline PAtomicInteger(int v = 0)
00227         : value(v) { }
00228       BOOL IsZero() const                { return value == 0; }
00229       inline int operator++()            { PWaitAndSignal m(critSec); value++; return value;}
00230       inline int operator--()            { PWaitAndSignal m(critSec); value--; return value;}
00231       inline operator int () const       { return value; }
00232       inline void SetValue(int v)        { value = v; }
00233    private:
00234       PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; }
00235     protected:
00236       int value;
00237 #endif
00238 };
00239 
00240 #endif
00241 
00242 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Sep 21 14:40:11 2007 for PWLib by  doxygen 1.5.3