# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

reader_writer.h

Go to the documentation of this file.
00001 
00006 /* Copyright, 2001 Nevrax Ltd.
00007  *
00008  * This file is part of NEVRAX NEL.
00009  * NEVRAX NEL is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2, or (at your option)
00012  * any later version.
00013 
00014  * NEVRAX NEL is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017  * General Public License for more details.
00018 
00019  * You should have received a copy of the GNU General Public License
00020  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00022  * MA 02111-1307, USA.
00023  */
00024 
00025 #ifndef NL_READER_WRITER_H
00026 #define NL_READER_WRITER_H
00027 
00028 #include "nel/misc/types_nl.h"
00029 #include "nel/misc/mutex.h"
00030 
00031 
00032 namespace NLMISC {
00033 
00040 class CReaderWriter
00041 {
00042 private:
00043 
00044         volatile CMutex _Fairness;
00045         volatile CMutex _ReadersMutex;
00046         volatile CMutex _RWMutex;
00047         volatile sint   _ReadersLevel;
00048 
00049 public:
00050 
00051         CReaderWriter();
00052         ~CReaderWriter();
00053 
00054         void                    enterReader()
00055         {
00056                 const_cast<CMutex&>(_Fairness).enter();
00057                 const_cast<CMutex&>(_ReadersMutex).enter();
00058                 ++_ReadersLevel;
00059                 if (_ReadersLevel == 1)
00060                         const_cast<CMutex&>(_RWMutex).enter();
00061                 const_cast<CMutex&>(_ReadersMutex).leave();
00062                 const_cast<CMutex&>(_Fairness).leave();
00063         }
00064 
00065         void                    leaveReader()
00066         {
00067                 const_cast<CMutex&>(_ReadersMutex).enter();
00068                 --_ReadersLevel;
00069                 if (_ReadersLevel == 0)
00070                         const_cast<CMutex&>(_RWMutex).leave();
00071                 const_cast<CMutex&>(_ReadersMutex).leave();
00072         }
00073 
00074         void                    enterWriter()
00075         {
00076                 const_cast<CMutex&>(_Fairness).enter();
00077                 const_cast<CMutex&>(_RWMutex).enter();
00078                 const_cast<CMutex&>(_Fairness).leave();
00079         }
00080 
00081         void                    leaveWriter()
00082         {
00083                 const_cast<CMutex&>(_RWMutex).leave();
00084         }
00085 };
00086 
00093 template <class T>
00094 class CRWSynchronized
00095 {
00096 public:
00097 
00098         class CReadAccessor
00099         {
00100                 CRWSynchronized<T>              *_RWSynchronized;
00101 
00102         public:
00103 
00104                 CReadAccessor(CRWSynchronized<T> *cs)
00105                 {
00106                         _RWSynchronized = cs;
00107                         const_cast<CReaderWriter&>(_RWSynchronized->_RWSync).enterReader();
00108                 }
00109 
00110                 ~CReadAccessor()
00111                 {
00112                         const_cast<CReaderWriter&>(_RWSynchronized->_RWSync).leaveReader();
00113                 }
00114 
00115                 const T         &value()
00116                 {
00117                         return const_cast<const T&>(_RWSynchronized->_Value);
00118                 }
00119         };
00120 
00121         class CWriteAccessor
00122         {
00123                 CRWSynchronized<T>              *_RWSynchronized;
00124 
00125         public:
00126 
00127                 CWriteAccessor(CRWSynchronized<T> *cs)
00128                 {
00129                         _RWSynchronized = cs;
00130                         const_cast<CReaderWriter&>(_RWSynchronized->_RWSync).enterWriter();
00131                 }
00132 
00133                 ~CWriteAccessor()
00134                 {
00135                         const_cast<CReaderWriter&>(_RWSynchronized->_RWSync).leaveWriter();
00136                 }
00137 
00138                 T               &value()
00139                 {
00140                         return const_cast<T&>(_RWSynchronized->_Value);
00141                 }
00142         };
00143 
00144 private:
00145         friend class CRWSynchronized::CReadAccessor;
00146         friend class CRWSynchronized::CWriteAccessor;
00147 
00148         volatile CReaderWriter          _RWSync;
00149 
00150         volatile T                                      _Value;
00151 
00152 };
00153 
00154 } // NLMISC
00155 
00156 
00157 #endif // NL_READER_WRITER_H
00158 
00159 /* End of reader_writer.h */