1*f8e07b45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*f8e07b45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*f8e07b45SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*f8e07b45SAndrew Rist * distributed with this work for additional information 6*f8e07b45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*f8e07b45SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*f8e07b45SAndrew Rist * "License"); you may not use this file except in compliance 9*f8e07b45SAndrew Rist * with the License. You may obtain a copy of the License at 10*f8e07b45SAndrew Rist * 11*f8e07b45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*f8e07b45SAndrew Rist * 13*f8e07b45SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*f8e07b45SAndrew Rist * software distributed under the License is distributed on an 15*f8e07b45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*f8e07b45SAndrew Rist * KIND, either express or implied. See the License for the 17*f8e07b45SAndrew Rist * specific language governing permissions and limitations 18*f8e07b45SAndrew Rist * under the License. 19*f8e07b45SAndrew Rist * 20*f8e07b45SAndrew Rist *************************************************************/ 21*f8e07b45SAndrew Rist 22*f8e07b45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ 25cdf0e10cSrcweir #define __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ 26cdf0e10cSrcweir 27cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 28cdf0e10cSrcweir // my own includes 29cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include <threadhelp/inoncopyable.h> 32cdf0e10cSrcweir #include <threadhelp/irwlock.h> 33cdf0e10cSrcweir 34cdf0e10cSrcweir //#ifndef __FRAMEWORK_THREADHELP_THREADHELPBASE_HXX_ 35cdf0e10cSrcweir //#include <threadhelp/threadhelpbase.hxx> 36cdf0e10cSrcweir //#endif 37cdf0e10cSrcweir 38cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 39cdf0e10cSrcweir // interface includes 40cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 41cdf0e10cSrcweir 42cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 43cdf0e10cSrcweir // other includes 44cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 45cdf0e10cSrcweir 46cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 47cdf0e10cSrcweir // namespace 48cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 49cdf0e10cSrcweir 50cdf0e10cSrcweir namespace framework{ 51cdf0e10cSrcweir 52cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 53cdf0e10cSrcweir // const 54cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 55cdf0e10cSrcweir 56cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 57cdf0e10cSrcweir // declarations 58cdf0e10cSrcweir //_________________________________________________________________________________________________________________ 59cdf0e10cSrcweir 60cdf0e10cSrcweir /*-************************************************************************************************************//** 61cdf0e10cSrcweir @short implement a guard to set write locks 62cdf0e10cSrcweir @descr This guard should be used to set a lock for reading AND writing object internal member. 63cdf0e10cSrcweir We never need a own mutex to safe our internal member access - because 64cdf0e10cSrcweir a guard is used as function-local member only. There exist no multithreaded access to it realy ... 65cdf0e10cSrcweir 66cdf0e10cSrcweir @attention a) To prevent us against wrong using, the default ctor, copy ctor and the =operator are maked private! 67cdf0e10cSrcweir b) Use interface "IRWLock" of set LockHelper only - because we must support a finer granularity of locking. 68cdf0e10cSrcweir Interface "IMutex" should be used by easier guard implementations ... like "ResetableGuard"! 69cdf0e10cSrcweir 70cdf0e10cSrcweir @implements - 71cdf0e10cSrcweir @base INonCopyable 72cdf0e10cSrcweir 73cdf0e10cSrcweir @devstatus ready to use 74cdf0e10cSrcweir *//*-*************************************************************************************************************/ 75cdf0e10cSrcweir class WriteGuard : private INonCopyable 76cdf0e10cSrcweir { 77cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 78cdf0e10cSrcweir // public methods 79cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 80cdf0e10cSrcweir public: 81cdf0e10cSrcweir 82cdf0e10cSrcweir /*-****************************************************************************************************//** 83cdf0e10cSrcweir @short ctor 84cdf0e10cSrcweir @descr These ctors initialize the guard with a reference to used lock member of object to protect. 85cdf0e10cSrcweir Null isn't allowed as value! 86cdf0e10cSrcweir 87cdf0e10cSrcweir @seealso - 88cdf0e10cSrcweir 89cdf0e10cSrcweir @param "pLock" ,reference to used lock member of object to protect 90cdf0e10cSrcweir @param "rLock" ,reference to used lock member of object to protect 91cdf0e10cSrcweir @return - 92cdf0e10cSrcweir 93cdf0e10cSrcweir @onerror - 94cdf0e10cSrcweir *//*-*****************************************************************************************************/ WriteGuard(IRWLock * pLock)95cdf0e10cSrcweir inline WriteGuard( IRWLock* pLock ) 96cdf0e10cSrcweir : m_pLock ( pLock ) 97cdf0e10cSrcweir , m_eMode ( E_NOLOCK ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir lock(); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir 102cdf0e10cSrcweir //********************************************************************************************************* WriteGuard(IRWLock & rLock)103cdf0e10cSrcweir inline WriteGuard( IRWLock& rLock ) 104cdf0e10cSrcweir : m_pLock ( &rLock ) 105cdf0e10cSrcweir , m_eMode ( E_NOLOCK ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir lock(); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir /*-****************************************************************************************************//** 111cdf0e10cSrcweir @short dtor 112cdf0e10cSrcweir @descr We unlock the used lock member automaticly if user forget it. 113cdf0e10cSrcweir 114cdf0e10cSrcweir @seealso - 115cdf0e10cSrcweir 116cdf0e10cSrcweir @param - 117cdf0e10cSrcweir @return - 118cdf0e10cSrcweir 119cdf0e10cSrcweir @onerror - 120cdf0e10cSrcweir *//*-*****************************************************************************************************/ ~WriteGuard()121cdf0e10cSrcweir inline ~WriteGuard() 122cdf0e10cSrcweir { 123cdf0e10cSrcweir unlock(); 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir /*-****************************************************************************************************//** 127cdf0e10cSrcweir @short set write lock 128cdf0e10cSrcweir @descr Call this method to set the write lock. The call will block till all current threads are synchronized! 129cdf0e10cSrcweir 130cdf0e10cSrcweir @seealso method unlock() 131cdf0e10cSrcweir 132cdf0e10cSrcweir @param - 133cdf0e10cSrcweir @return - 134cdf0e10cSrcweir 135cdf0e10cSrcweir @onerror - 136cdf0e10cSrcweir *//*-*****************************************************************************************************/ lock()137cdf0e10cSrcweir inline void lock() 138cdf0e10cSrcweir { 139cdf0e10cSrcweir switch( m_eMode ) 140cdf0e10cSrcweir { 141cdf0e10cSrcweir case E_NOLOCK : { 142cdf0e10cSrcweir // Acquire write access and set return state. 143cdf0e10cSrcweir // Mode is set later if it was successful! 144cdf0e10cSrcweir m_pLock->acquireWriteAccess(); 145cdf0e10cSrcweir m_eMode = E_WRITELOCK; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir break; 148cdf0e10cSrcweir case E_READLOCK : { 149cdf0e10cSrcweir // User has downgrade to read access before! 150cdf0e10cSrcweir // We must release it before we can set a new write access! 151cdf0e10cSrcweir m_pLock->releaseReadAccess(); 152cdf0e10cSrcweir m_pLock->acquireWriteAccess(); 153cdf0e10cSrcweir m_eMode = E_WRITELOCK; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir break; 156cdf0e10cSrcweir default: break; // nothing to do 157cdf0e10cSrcweir } 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir /*-****************************************************************************************************//** 161cdf0e10cSrcweir @short unset write lock 162cdf0e10cSrcweir @descr Call this method to unlock the rw-lock temp.! 163cdf0e10cSrcweir Normaly we do it at dtor automaticly for you ... 164cdf0e10cSrcweir 165cdf0e10cSrcweir @seealso method lock() 166cdf0e10cSrcweir 167cdf0e10cSrcweir @param - 168cdf0e10cSrcweir @return - 169cdf0e10cSrcweir 170cdf0e10cSrcweir @onerror - 171cdf0e10cSrcweir *//*-*****************************************************************************************************/ unlock()172cdf0e10cSrcweir inline void unlock() 173cdf0e10cSrcweir { 174cdf0e10cSrcweir switch( m_eMode ) 175cdf0e10cSrcweir { 176cdf0e10cSrcweir case E_READLOCK : { 177cdf0e10cSrcweir // User has downgraded to a read lock before! 178cdf0e10cSrcweir // => There isn't realy a write lock ... 179cdf0e10cSrcweir m_pLock->releaseReadAccess(); 180cdf0e10cSrcweir m_eMode = E_NOLOCK; 181cdf0e10cSrcweir } 182cdf0e10cSrcweir break; 183cdf0e10cSrcweir case E_WRITELOCK : { 184cdf0e10cSrcweir m_pLock->releaseWriteAccess(); 185cdf0e10cSrcweir m_eMode = E_NOLOCK; 186cdf0e10cSrcweir } 187cdf0e10cSrcweir break; 188cdf0e10cSrcweir default: break; // nothing to do 189cdf0e10cSrcweir } 190cdf0e10cSrcweir } 191cdf0e10cSrcweir 192cdf0e10cSrcweir /*-****************************************************************************************************//** 193cdf0e10cSrcweir @short downgrade write access to read access without new blocking! 194cdf0e10cSrcweir @descr If this write lock is set you can change it to a "read lock". 195cdf0e10cSrcweir An "upgrade" is the same like new calling "lock()"! 196cdf0e10cSrcweir 197cdf0e10cSrcweir @seealso - 198cdf0e10cSrcweir 199cdf0e10cSrcweir @param - 200cdf0e10cSrcweir @return - 201cdf0e10cSrcweir 202cdf0e10cSrcweir @onerror - 203cdf0e10cSrcweir *//*-*****************************************************************************************************/ downgrade()204cdf0e10cSrcweir inline void downgrade() 205cdf0e10cSrcweir { 206cdf0e10cSrcweir if( m_eMode == E_WRITELOCK ) 207cdf0e10cSrcweir { 208cdf0e10cSrcweir m_pLock->downgradeWriteAccess(); 209cdf0e10cSrcweir m_eMode = E_READLOCK; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir } 212cdf0e10cSrcweir 213cdf0e10cSrcweir /*-****************************************************************************************************//** 214cdf0e10cSrcweir @short return internal states 215cdf0e10cSrcweir @descr For user they dont know what they are doing ... 216cdf0e10cSrcweir 217cdf0e10cSrcweir @seealso - 218cdf0e10cSrcweir 219cdf0e10cSrcweir @param - 220cdf0e10cSrcweir @return Current set lock mode. 221cdf0e10cSrcweir 222cdf0e10cSrcweir @onerror No error should occure. 223cdf0e10cSrcweir *//*-*****************************************************************************************************/ getMode() const224cdf0e10cSrcweir inline ELockMode getMode() const 225cdf0e10cSrcweir { 226cdf0e10cSrcweir return m_eMode; 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 230cdf0e10cSrcweir // private methods 231cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 232cdf0e10cSrcweir private: 233cdf0e10cSrcweir 234cdf0e10cSrcweir /*-****************************************************************************************************//** 235cdf0e10cSrcweir @short disable using of these functions! 236cdf0e10cSrcweir @descr It's not allowed to use this methods. Different problem can occure otherwise. 237cdf0e10cSrcweir Thats why we disable it by make it private. 238cdf0e10cSrcweir 239cdf0e10cSrcweir @seealso other ctor 240cdf0e10cSrcweir 241cdf0e10cSrcweir @param - 242cdf0e10cSrcweir @return - 243cdf0e10cSrcweir 244cdf0e10cSrcweir @onerror - 245cdf0e10cSrcweir *//*-*****************************************************************************************************/ 246cdf0e10cSrcweir WriteGuard(); 247cdf0e10cSrcweir 248cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 249cdf0e10cSrcweir // private member 250cdf0e10cSrcweir //------------------------------------------------------------------------------------------------------------- 251cdf0e10cSrcweir private: 252cdf0e10cSrcweir 253cdf0e10cSrcweir IRWLock* m_pLock ; /// reference to lock-member of protected object 254cdf0e10cSrcweir ELockMode m_eMode ; /// protection against multiple lock calls without unlock and difference between supported lock modi 255cdf0e10cSrcweir 256cdf0e10cSrcweir }; // class WriteGuard 257cdf0e10cSrcweir 258cdf0e10cSrcweir } // namespace framework 259cdf0e10cSrcweir 260cdf0e10cSrcweir #endif // #ifndef __FRAMEWORK_THREADHELP_WRITEGUARD_HXX_ 261