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.19  2006/09/22 00:32:21  csoutheren
00028  * Forced PAtomicInteger::operator= to be private in all compile paths
00029  *
00030  * Revision 1.18  2006/08/07 06:41:16  csoutheren
00031  * Add PCriticalSection::Clone
00032  *
00033  * Revision 1.17  2006/03/20 00:24:56  csoutheren
00034  * Applied patch #1446482
00035  * Thanks to Adam Butcher
00036  *
00037  * Revision 1.16  2006/01/18 07:17:59  csoutheren
00038  * Added explicit copy constructor for PCriticalSection on Windows
00039  *
00040  * Revision 1.15  2005/11/30 12:47:37  csoutheren
00041  * Removed tabs, reformatted some code, and changed tags for Doxygen
00042  *
00043  * Revision 1.14  2005/11/25 03:43:47  csoutheren
00044  * Fixed function argument comments to be compatible with Doxygen
00045  *
00046  * Revision 1.13  2005/11/14 22:29:13  csoutheren
00047  * Reverted Wait and Signal to non-const - there is no way we can guarantee that all
00048  * descendant classes everywhere will be changed over, so we have to keep the
00049  * original  API
00050  *
00051  * Revision 1.12  2005/11/08 10:44:37  dsandras
00052  * Fixed deadlock with code using the old API.
00053  *
00054  * Revision 1.11  2005/11/04 07:20:30  csoutheren
00055  * Provide backwards compatibility functions and typedefs
00056  *
00057  * Revision 1.10  2005/11/04 06:34:20  csoutheren
00058  * Added new class PSync as abstract base class for all mutex/sempahore classes
00059  * Changed PCriticalSection to use Wait/Signal rather than Enter/Leave
00060  * Changed Wait/Signal to be const member functions
00061  * Renamed PMutex to PTimedMutex and made PMutex synonym for PCriticalSection.
00062  * This allows use of very efficient mutex primitives in 99% of cases where timed waits
00063  * are not needed
00064  *
00065  * Revision 1.9  2004/05/16 23:31:07  csoutheren
00066  * Updated API documentation
00067  *
00068  * Revision 1.8  2004/05/12 04:36:13  csoutheren
00069  * Fixed problems with using sem_wait and friends on systems that do not
00070  * support atomic integers
00071  *
00072  * Revision 1.7  2004/04/21 11:22:56  csoutheren
00073  * Modified to work with gcc 3.4.0
00074  *
00075  * Revision 1.6  2004/04/14 06:58:00  csoutheren
00076  * Fixed PAtomicInteger and PSmartPointer to use real atomic operations
00077  *
00078  * Revision 1.5  2004/04/12 03:35:26  csoutheren
00079  * Fixed problems with non-recursuve mutexes and critical sections on
00080  * older compilers and libc
00081  *
00082  * Revision 1.4  2004/04/12 00:58:45  csoutheren
00083  * Fixed PAtomicInteger on Linux, and modified PMutex to use it
00084  *
00085  * Revision 1.3  2004/04/12 00:36:04  csoutheren
00086  * Added new class PAtomicInteger and added Windows implementation
00087  *
00088  * Revision 1.2  2004/04/11 03:20:41  csoutheren
00089  * Added Unix implementation of PCriticalSection
00090  *
00091  * Revision 1.1  2004/04/11 02:55:17  csoutheren
00092  * Added PCriticalSection for Windows
00093  * Added compile time option for PContainer to use critical sections to provide thread safety under some circumstances
00094  *
00095  */
00096 
00097 #ifndef _PCRITICALSECTION
00098 #define _PCRITICALSECTION
00099 
00100 #include <ptlib/psync.h>
00101 
00102 #if P_HAS_ATOMIC_INT
00103 #if P_NEEDS_GNU_CXX_NAMESPACE
00104 #define EXCHANGE_AND_ADD(v,i)   __gnu_cxx::__exchange_and_add(v,i)
00105 #else
00106 #define EXCHANGE_AND_ADD(v,i)   __exchange_and_add(v,i)
00107 #endif
00108 #endif
00109 
00116 class PCriticalSection : public PSync
00117 {
00118   PCLASSINFO(PCriticalSection, PSync);
00119 
00120   public:
00125     PCriticalSection();
00126     PCriticalSection(const PCriticalSection &);
00127 
00130     ~PCriticalSection();
00132 
00137     void Wait();
00138     inline void Enter()
00139     { Wait(); }
00140 
00143     void Signal();
00144     inline void Leave()
00145     { Signal(); }
00146 
00149     PObject * Clone() const
00150     { return new PCriticalSection(); }
00151 
00153 
00154   private:
00155     PCriticalSection & operator=(const PCriticalSection &) { return *this; }
00156 
00157 // Include platform dependent part of class
00158 #ifdef _WIN32
00159 #include "msos/ptlib/critsec.h"
00160 #else
00161 #include "unix/ptlib/critsec.h"
00162 #endif
00163 };
00164 
00165 typedef PWaitAndSignal PEnterAndLeave;
00166 
00175 class PAtomicInteger 
00176 {
00177 #if defined(_WIN32) || defined(DOC_PLUS_PLUS)
00178     public:
00181       inline PAtomicInteger(
00182         long v = 0                     
00183       )
00184         : value(v) { }
00185 
00193       BOOL IsZero() const                 { return value == 0; }
00194 
00200       inline long operator++()            { return InterlockedIncrement(&value); }
00201 
00207       inline long operator--()            { return InterlockedDecrement(&value); }
00208 
00212       inline operator long () const       { return value; }
00213 
00217       inline void SetValue(
00218         long v                          
00219       )
00220       { value = v; }
00221     protected:
00222       long value;
00223 #elif defined(_STLP_INTERNAL_THREADS_H) && defined(_STLP_ATOMIC_EXCHANGE)
00224     public:
00225       inline PAtomicInteger(__stl_atomic_t v = 0)
00226         : value(v) { }
00227       BOOL IsZero() const                { return value == 0; }
00228       inline int operator++()            { return _STLP_ATOMIC_INCREMENT(&value); }
00229       inline int unsigned operator--()   { return _STLP_ATOMIC_DECREMENT(&value); }
00230       inline operator int () const       { return value; }
00231       inline void SetValue(int v)        { value = v; }
00232     protected:
00233       __stl_atomic_t value;
00234 #elif !defined(_STLP_INTERNAL_THREADS_H) && P_HAS_ATOMIC_INT
00235     public:
00236       inline PAtomicInteger(int v = 0)
00237         : value(v) { }
00238       BOOL IsZero() const                { return value == 0; }
00239       inline int operator++()            { return EXCHANGE_AND_ADD(&value, 1) + 1; }
00240       inline int unsigned operator--()   { return EXCHANGE_AND_ADD(&value, -1) - 1; }
00241       inline operator int () const       { return value; }
00242       inline void SetValue(int v)        { value = v; }
00243     protected:
00244       _Atomic_word value;
00245 #else 
00246     protected:
00247       PCriticalSection critSec;
00248     public:
00249       inline PAtomicInteger(int v = 0)
00250         : value(v) { }
00251       BOOL IsZero() const                { return value == 0; }
00252       inline int operator++()            { PWaitAndSignal m(critSec); value++; return value;}
00253       inline int operator--()            { PWaitAndSignal m(critSec); value--; return value;}
00254       inline operator int () const       { return value; }
00255       inline void SetValue(int v)        { value = v; }
00256     protected:
00257       int value;
00258 #endif
00259     private:
00260       PAtomicInteger & operator=(const PAtomicInteger & ref) { value = (int)ref; return *this; }
00261 };
00262 
00263 #endif
00264 
00265 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Sep 1 09:41:06 2008 for PWLib by  doxygen 1.5.6