diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index 274d0ba7f86..f28b3fb8a30 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -6,9 +6,7 @@ #include "qplatformdefs.h" #include "qreadwritelock.h" -#include "qmutex.h" #include "qthread.h" -#include "qwaitcondition.h" #include "qreadwritelock_p.h" #include "qelapsedtimer.h" #include "private/qfreelist_p.h" @@ -30,15 +28,11 @@ QT_BEGIN_NAMESPACE * - In any other case, d_ptr points to an actual QReadWriteLockPrivate. */ +using namespace QReadWriteLockStates; namespace { using ms = std::chrono::milliseconds; -enum { - StateMask = 0x3, - StateLockedForRead = 0x1, - StateLockedForWrite = 0x2, -}; const auto dummyLockedForRead = reinterpret_cast(quintptr(StateLockedForRead)); const auto dummyLockedForWrite = reinterpret_cast(quintptr(StateLockedForWrite)); inline bool isUncontendedLocked(const QReadWriteLockPrivate *d) @@ -411,26 +405,6 @@ void QReadWriteLock::unlock() } } -/*! \internal Helper for QWaitCondition::wait */ -QReadWriteLock::StateForWaitCondition QReadWriteLock::stateForWaitCondition() const -{ - QReadWriteLockPrivate *d = d_ptr.loadAcquire(); - switch (quintptr(d) & StateMask) { - case StateLockedForRead: return LockedForRead; - case StateLockedForWrite: return LockedForWrite; - } - - if (!d) - return Unlocked; - const auto lock = qt_scoped_lock(d->mutex); - if (d->writerCount > 1) - return RecursivelyLocked; - else if (d->writerCount == 1) - return LockedForWrite; - return LockedForRead; - -} - bool QReadWriteLockPrivate::lockForRead(std::unique_lock &lock, int timeout) { Q_ASSERT(!mutex.try_lock()); // mutex must be locked when entering this function diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h index 8e96e23ad2e..60078b8f55b 100644 --- a/src/corelib/thread/qreadwritelock.h +++ b/src/corelib/thread/qreadwritelock.h @@ -34,10 +34,7 @@ public: private: Q_DISABLE_COPY(QReadWriteLock) QAtomicPointer d_ptr; - - enum StateForWaitCondition { LockedForRead, LockedForWrite, Unlocked, RecursivelyLocked }; - StateForWaitCondition stateForWaitCondition() const; - friend class QWaitCondition; + friend class QReadWriteLockPrivate; }; #if defined(Q_CC_MSVC) diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h index e1d42fbbf30..e8379fcb568 100644 --- a/src/corelib/thread/qreadwritelock_p.h +++ b/src/corelib/thread/qreadwritelock_p.h @@ -16,14 +16,29 @@ // We mean it. // -#include +#include #include +#include #include QT_REQUIRE_CONFIG(thread); QT_BEGIN_NAMESPACE +namespace QReadWriteLockStates { +enum { + StateMask = 0x3, + StateLockedForRead = 0x1, + StateLockedForWrite = 0x2, +}; +enum StateForWaitCondition { + LockedForRead, + LockedForWrite, + Unlocked, + RecursivelyLocked +}; +} + class QReadWriteLockPrivate { public: @@ -63,8 +78,33 @@ public: bool recursiveLockForWrite(int timeout); bool recursiveLockForRead(int timeout); void recursiveUnlock(); + + static QReadWriteLockStates::StateForWaitCondition + stateForWaitCondition(const QReadWriteLock *lock); }; -Q_DECLARE_TYPEINFO(QReadWriteLockPrivate::Reader, Q_PRIMITIVE_TYPE); +Q_DECLARE_TYPEINFO(QReadWriteLockPrivate::Reader, Q_PRIMITIVE_TYPE);\ + +/*! \internal Helper for QWaitCondition::wait */ +inline QReadWriteLockStates::StateForWaitCondition +QReadWriteLockPrivate::stateForWaitCondition(const QReadWriteLock *q) +{ + using namespace QReadWriteLockStates; + QReadWriteLockPrivate *d = q->d_ptr.loadAcquire(); + switch (quintptr(d) & StateMask) { + case StateLockedForRead: return LockedForRead; + case StateLockedForWrite: return LockedForWrite; + } + + if (!d) + return Unlocked; + const auto lock = qt_scoped_lock(d->mutex); + if (d->writerCount > 1) + return RecursivelyLocked; + else if (d->writerCount == 1) + return LockedForWrite; + return LockedForRead; + +} QT_END_NAMESPACE diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp index 51e350e9dcd..c97023d996d 100644 --- a/src/corelib/thread/qwaitcondition_unix.cpp +++ b/src/corelib/thread/qwaitcondition_unix.cpp @@ -173,12 +173,14 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline) { + using namespace QReadWriteLockStates; + if (!readWriteLock) return false; - auto previousState = readWriteLock->stateForWaitCondition(); - if (previousState == QReadWriteLock::Unlocked) + auto previousState = QReadWriteLockPrivate::stateForWaitCondition(readWriteLock); + if (previousState == Unlocked) return false; - if (previousState == QReadWriteLock::RecursivelyLocked) { + if (previousState == RecursivelyLocked) { qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()"); return false; } @@ -190,7 +192,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline bool returnValue = d->wait(deadline); - if (previousState == QReadWriteLock::LockedForWrite) + if (previousState == LockedForWrite) readWriteLock->lockForWrite(); else readWriteLock->lockForRead(); diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp index 2152ae551f0..c176241f474 100644 --- a/src/corelib/thread/qwaitcondition_win.cpp +++ b/src/corelib/thread/qwaitcondition_win.cpp @@ -145,12 +145,14 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline) bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) { + using namespace QReadWriteLockStates; + if (!readWriteLock) return false; - auto previousState = readWriteLock->stateForWaitCondition(); - if (previousState == QReadWriteLock::Unlocked) + auto previousState = QReadWriteLockPrivate::stateForWaitCondition(readWriteLock); + if (previousState == Unlocked) return false; - if (previousState == QReadWriteLock::RecursivelyLocked) { + if (previousState == RecursivelyLocked) { qWarning("QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()"); return false; } @@ -160,7 +162,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) bool returnValue = d->wait(wce, time); - if (previousState == QReadWriteLock::LockedForWrite) + if (previousState == LockedForWrite) readWriteLock->lockForWrite(); else readWriteLock->lockForRead();