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