29class QReadWriteLockPrivate
33 static constexpr quintptr StateLockedForRead = QReadWriteLock::StateLockedForRead;
34 static constexpr quintptr StateLockedForWrite = QReadWriteLock::StateLockedForWrite;
35 static constexpr quintptr StateMask = QReadWriteLock::StateMask;
36 static constexpr quintptr MultiplyLocked = QReadWriteLock::Counter;
37 static constexpr quintptr IsRecursiveLock = MultiplyLocked << 1;
38 static constexpr quintptr RecursivelyLockedForWrite =
39 StateLockedForWrite | MultiplyLocked | IsRecursiveLock;
41 explicit QReadWriteLockPrivate(
bool isRecursive =
false)
42 : recursive(isRecursive) {}
44 alignas(QtPrivate::IdealMutexAlignment) std::condition_variable writerCond;
45 std::condition_variable readerCond;
47 alignas(QtPrivate::IdealMutexAlignment) std::mutex mutex;
50 int waitingReaders = 0;
51 int waitingWriters = 0;
55 bool lockForWrite(std::unique_lock<std::mutex> &lock, QDeadlineTimer timeout);
56 bool lockForRead(std::unique_lock<std::mutex> &lock, QDeadlineTimer timeout);
62 static QReadWriteLockPrivate *allocate();
65 Qt::HANDLE currentWriter = {};
72 QVarLengthArray<Reader, 16> currentReaders;
75 bool recursiveLockForWrite(QDeadlineTimer timeout);
76 bool recursiveLockForRead(QDeadlineTimer timeout);
77 void recursiveUnlock();
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 static quintptr describeState(
void *dd)
noexcept
96 quintptr u = quintptr(dd);
102 auto d =
static_cast<QReadWriteLockPrivate *>(dd);
103 const auto lock = qt_scoped_lock(d->mutex);
106 u |= StateLockedForWrite;
107 else if (d->readerCount)
108 u |= StateLockedForRead;
110 u |= IsRecursiveLock;
111 if (d->writerCount > 1) {
113 Q_ASSERT(u == RecursivelyLockedForWrite);
117 Q_ASSERT(d->writerCount <= 1);
123 template <
typename Prep,
typename DoWait>
124 static bool waitConditionWait(QReadWriteLock *readWriteLock, Prep &&prep, DoWait &&doWait);
129inline bool QReadWriteLockPrivate::waitConditionWait(QReadWriteLock *readWriteLock, Prep &&prep, DoWait &&doWait)
133 auto previousState = describeState(readWriteLock->d_ptr.loadAcquire());
134 if (previousState == 0)
136 if (previousState == RecursivelyLockedForWrite) {
137 qWarning(
"QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
142 readWriteLock->unlock();
143 bool returnValue = doWait();
146 if (previousState & StateLockedForWrite)
147 readWriteLock->lockForWrite();
149 readWriteLock->lockForRead();