qreadwritelock.h

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00004 ** All rights reserved.
00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
00006 **
00007 ** This file is part of the QtCore module of the Qt Toolkit.
00008 **
00009 ** $QT_BEGIN_LICENSE:LGPL$
00010 ** Commercial Usage
00011 ** Licensees holding valid Qt Commercial licenses may use this file in
00012 ** accordance with the Qt Commercial License Agreement provided with the
00013 ** Software or, alternatively, in accordance with the terms contained in
00014 ** a written agreement between you and Nokia.
00015 **
00016 ** GNU Lesser General Public License Usage
00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
00018 ** General Public License version 2.1 as published by the Free Software
00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
00020 ** packaging of this file.  Please review the following information to
00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
00023 **
00024 ** In addition, as a special exception, Nokia gives you certain additional
00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
00027 **
00028 ** GNU General Public License Usage
00029 ** Alternatively, this file may be used under the terms of the GNU
00030 ** General Public License version 3.0 as published by the Free Software
00031 ** Foundation and appearing in the file LICENSE.GPL included in the
00032 ** packaging of this file.  Please review the following information to
00033 ** ensure the GNU General Public License version 3.0 requirements will be
00034 ** met: http://www.gnu.org/copyleft/gpl.html.
00035 **
00036 ** If you have questions regarding the use of this file, please contact
00037 ** Nokia at qt-info@nokia.com.
00038 ** $QT_END_LICENSE$
00039 **
00040 ****************************************************************************/
00041 
00042 #ifndef QREADWRITELOCK_H
00043 #define QREADWRITELOCK_H
00044 
00045 #include <QtCore/qglobal.h>
00046 #include <limits.h> // ### Qt 5: remove
00047 
00048 QT_BEGIN_HEADER
00049 
00050 QT_BEGIN_NAMESPACE
00051 
00052 QT_MODULE(Core)
00053 
00054 #ifndef QT_NO_THREAD
00055 
00056 struct QReadWriteLockPrivate;
00057 
00058 class Q_CORE_EXPORT QReadWriteLock
00059 {
00060 public:
00061     enum RecursionMode { NonRecursive, Recursive };
00062 
00063     QReadWriteLock(); // ### Qt 5: merge with below
00064     QReadWriteLock(RecursionMode recursionMode);
00065     ~QReadWriteLock();
00066 
00067     void lockForRead();
00068     bool tryLockForRead();
00069     bool tryLockForRead(int timeout);
00070 
00071     void lockForWrite();
00072     bool tryLockForWrite();
00073     bool tryLockForWrite(int timeout);
00074 
00075     void unlock();
00076 
00077 private:
00078     Q_DISABLE_COPY(QReadWriteLock)
00079     QReadWriteLockPrivate *d;
00080 
00081     friend class QWaitCondition;
00082 };
00083 
00084 #if defined(Q_CC_MSVC)
00085 #pragma warning( push )
00086 #pragma warning( disable : 4312 ) // ignoring the warning from /Wp64
00087 #endif
00088 
00089 class Q_CORE_EXPORT QReadLocker
00090 {
00091 public:
00092     inline QReadLocker(QReadWriteLock *readWriteLock);
00093 
00094     inline ~QReadLocker()
00095     { unlock(); }
00096 
00097     inline void unlock()
00098     {
00099         if (q_val) {
00100             if ((q_val & quintptr(1u)) == quintptr(1u)) {
00101                 q_val &= ~quintptr(1u);
00102                 readWriteLock()->unlock();
00103             }
00104         }
00105     }
00106 
00107     inline void relock()
00108     {
00109         if (q_val) {
00110             if ((q_val & quintptr(1u)) == quintptr(0u)) {
00111                 readWriteLock()->lockForRead();
00112                 q_val |= quintptr(1u);
00113             }
00114         }
00115     }
00116 
00117     inline QReadWriteLock *readWriteLock() const
00118     { return reinterpret_cast<QReadWriteLock *>(q_val & ~quintptr(1u)); }
00119 
00120 private:
00121     Q_DISABLE_COPY(QReadLocker)
00122     quintptr q_val;
00123 };
00124 
00125 inline QReadLocker::QReadLocker(QReadWriteLock *areadWriteLock)
00126     : q_val(reinterpret_cast<quintptr>(areadWriteLock))
00127 {
00128     Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0),
00129                "QReadLocker", "QReadWriteLock pointer is misaligned");
00130     relock();
00131 }
00132 
00133 class Q_CORE_EXPORT QWriteLocker
00134 {
00135 public:
00136     inline QWriteLocker(QReadWriteLock *readWriteLock);
00137 
00138     inline ~QWriteLocker()
00139     { unlock(); }
00140 
00141     inline void unlock()
00142     {
00143         if (q_val) {
00144             if ((q_val & quintptr(1u)) == quintptr(1u)) {
00145                 q_val &= ~quintptr(1u);
00146                 readWriteLock()->unlock();
00147             }
00148         }
00149     }
00150 
00151     inline void relock()
00152     {
00153         if (q_val) {
00154             if ((q_val & quintptr(1u)) == quintptr(0u)) {
00155                 readWriteLock()->lockForWrite();
00156                 q_val |= quintptr(1u);
00157             }
00158         }
00159     }
00160 
00161     inline QReadWriteLock *readWriteLock() const
00162     { return reinterpret_cast<QReadWriteLock *>(q_val & ~quintptr(1u)); }
00163 
00164 
00165 private:
00166     Q_DISABLE_COPY(QWriteLocker)
00167     quintptr q_val;
00168 };
00169 
00170 inline QWriteLocker::QWriteLocker(QReadWriteLock *areadWriteLock)
00171     : q_val(reinterpret_cast<quintptr>(areadWriteLock))
00172 {
00173     Q_ASSERT_X((q_val & quintptr(1u)) == quintptr(0),
00174                "QWriteLocker", "QReadWriteLock pointer is misaligned");
00175     relock();
00176 }
00177 
00178 #if defined(Q_CC_MSVC)
00179 #pragma warning( pop )
00180 #endif
00181 
00182 #else // QT_NO_THREAD
00183 
00184 class Q_CORE_EXPORT QReadWriteLock
00185 {
00186 public:
00187     enum RecursionMode { NonRecursive, Recursive };
00188     inline explicit QReadWriteLock(RecursionMode = NonRecursive) { }
00189     inline ~QReadWriteLock() { }
00190 
00191     static inline void lockForRead() { }
00192     static inline bool tryLockForRead() { return true; }
00193     static inline bool tryLockForRead(int timeout) { Q_UNUSED(timeout); return true; }
00194 
00195     static inline void lockForWrite() { }
00196     static inline bool tryLockForWrite() { return true; }
00197     static inline bool tryLockForWrite(int timeout) { Q_UNUSED(timeout); return true; }
00198 
00199     static inline void unlock() { }
00200 
00201 private:
00202     Q_DISABLE_COPY(QReadWriteLock)
00203 };
00204 
00205 class Q_CORE_EXPORT QReadLocker
00206 {
00207 public:
00208     inline QReadLocker(QReadWriteLock *) { }
00209     inline ~QReadLocker() { }
00210 
00211     static inline void unlock() { }
00212     static inline void relock() { }
00213     static inline QReadWriteLock *readWriteLock() { return 0; }
00214 
00215 private:
00216     Q_DISABLE_COPY(QReadLocker)
00217 };
00218 
00219 class Q_CORE_EXPORT QWriteLocker
00220 {
00221 public:
00222     inline explicit QWriteLocker(QReadWriteLock *) { }
00223     inline ~QWriteLocker() { }
00224 
00225     static inline void unlock() { }
00226     static inline void relock() { }
00227     static inline QReadWriteLock *readWriteLock() { return 0; }
00228 
00229 private:
00230     Q_DISABLE_COPY(QWriteLocker)
00231 };
00232 
00233 #endif // QT_NO_THREAD
00234 
00235 QT_END_NAMESPACE
00236 
00237 QT_END_HEADER
00238 
00239 #endif // QREADWRITELOCK_H