blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2006, Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of 00014 * Vintela, Inc., 00015 * nor Novell, Inc., 00016 * nor the names of its contributors or employees may be used to 00017 * endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 * POSSIBILITY OF SUCH DAMAGE. 00031 *******************************************************************************/ 00032 00033 00039 #ifndef BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_ 00040 #define BLOCXX_RWLOCKER_HPP_INCLUDE_GUARD_ 00041 #include "blocxx/BLOCXX_config.h" 00042 #include "blocxx/GenericRWLockImpl.hpp" 00043 00044 namespace BLOCXX_NAMESPACE 00045 { 00046 00047 BLOCXX_DECLARE_APIEXCEPTION(RWLocker, BLOCXX_COMMON_API); 00049 // The locker is recursive and also supports upgrading a read-lock to a write lock 00050 class BLOCXX_COMMON_API RWLocker 00051 { 00052 public: 00053 RWLocker(); 00054 ~RWLocker(); 00055 00059 void getReadLock(const Timeout& timeout); 00060 void getReadLock(UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; 00061 00068 void getWriteLock(const Timeout& timeout); 00069 void getWriteLock(UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; 00070 00074 void releaseReadLock(); 00075 00079 void releaseWriteLock(); 00080 00081 private: 00082 // Have to do this because on some platforms one thread may have different values for 00083 // a Thread_t, and ThreadImpl::sameThreads() has to be called to know if they refer 00084 // to the same one. 00085 struct ThreadComparer 00086 { 00087 bool operator()(Thread_t x, Thread_t y) const; 00088 }; 00089 00090 GenericRWLockImpl<Thread_t, ThreadComparer> m_impl; 00091 00092 // unimplemented 00093 RWLocker(const RWLocker&); 00094 RWLocker& operator=(const RWLocker&); 00095 }; 00097 class BLOCXX_COMMON_API ReadLock 00098 { 00099 public: 00100 ReadLock(RWLocker& locker, const Timeout& timeout) 00101 : m_locker(&locker) 00102 , m_released(false) 00103 { 00104 m_locker->getReadLock(timeout); 00105 } 00106 ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; // in 4.0.0 00107 ~ReadLock() 00108 { 00109 release(); 00110 } 00111 void lock(const Timeout& timeout) 00112 { 00113 if (m_released) 00114 { 00115 m_locker->getReadLock(timeout); 00116 m_released = false; 00117 } 00118 } 00119 BLOCXX_DEPRECATED void lock(UInt32 sTimeout, UInt32 usTimeout=0) 00120 { 00121 if (m_released) 00122 { 00123 m_locker->getReadLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0)); 00124 m_released = false; 00125 } 00126 } 00127 void release() 00128 { 00129 if (!m_released) 00130 { 00131 m_locker->releaseReadLock(); 00132 m_released = true; 00133 } 00134 } 00135 private: 00136 RWLocker* m_locker; 00137 bool m_released; 00138 // noncopyable 00139 ReadLock(const ReadLock&); 00140 ReadLock& operator=(const ReadLock&); 00141 }; 00142 00143 inline 00144 ReadLock::ReadLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout) 00145 : m_locker(&locker) 00146 , m_released(false) 00147 { 00148 m_locker->getReadLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0)); 00149 } 00151 class BLOCXX_COMMON_API WriteLock 00152 { 00153 public: 00154 WriteLock(RWLocker& locker, const Timeout& timeout) 00155 : m_locker(&locker) 00156 , m_released(false) 00157 { 00158 m_locker->getWriteLock(timeout); 00159 } 00160 WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout=0) BLOCXX_DEPRECATED; // in 4.0.0 00161 ~WriteLock() 00162 { 00163 release(); 00164 } 00165 void lock(const Timeout& timeout) 00166 { 00167 if (m_released) 00168 { 00169 m_locker->getWriteLock(timeout); 00170 m_released = false; 00171 } 00172 } 00173 BLOCXX_DEPRECATED void lock(UInt32 sTimeout, UInt32 usTimeout=0) // in 4.0.0 00174 { 00175 if (m_released) 00176 { 00177 m_locker->getWriteLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0)); 00178 m_released = false; 00179 } 00180 } 00181 void release() 00182 { 00183 if (!m_released) 00184 { 00185 m_locker->releaseWriteLock(); 00186 m_released = true; 00187 } 00188 } 00189 private: 00190 RWLocker* m_locker; 00191 bool m_released; 00192 00193 // noncopyable 00194 WriteLock(const WriteLock&); 00195 WriteLock& operator=(const WriteLock&); 00196 }; 00197 00198 inline 00199 WriteLock::WriteLock(RWLocker& locker, UInt32 sTimeout, UInt32 usTimeout) 00200 : m_locker(&locker) 00201 , m_released(false) 00202 { 00203 m_locker->getWriteLock(Timeout::relative(sTimeout + static_cast<float>(usTimeout) * 1000000.0)); 00204 } 00205 00206 } // end namespace BLOCXX_NAMESPACE 00207 00208 #endif