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);
97 if (quintptr state = u & StateMask) {
105 auto d =
static_cast<QReadWriteLockPrivate *>(dd);
106 const auto lock = qt_scoped_lock(d->mutex);
109 u |= StateLockedForWrite;
110 else if (d->readerCount)
111 u |= StateLockedForRead;
113 u |= IsRecursiveLock;
114 if (d->writerCount > 1) {
116 Q_ASSERT(u == RecursivelyLockedForWrite);
120 Q_ASSERT(d->writerCount <= 1);
126 template <
typename Prep,
typename DoWait>
127 static bool waitConditionWait(QReadWriteLock *readWriteLock, Prep &&prep, DoWait &&doWait);
132inline bool QReadWriteLockPrivate::waitConditionWait(QReadWriteLock *readWriteLock, Prep &&prep, DoWait &&doWait)
136 auto previousState = describeState(readWriteLock->d_ptr.loadAcquire());
137 if (previousState == 0)
139 if (previousState == RecursivelyLockedForWrite) {
140 qWarning(
"QWaitCondition: cannot wait on QReadWriteLocks with recursive lockForWrite()");
145 readWriteLock->unlock();
146 bool returnValue = doWait();
149 if (previousState & StateLockedForWrite)
150 readWriteLock->lockForWrite();
152 readWriteLock->lockForRead();