6#include "qplatformdefs.h"
11#include "private/qfreelist_p.h"
12#include "private/qlocking_p.h"
33using steady_clock = std::chrono::steady_clock;
128 if (isUncontendedLocked(
d)) {
129 qWarning(
"QReadWriteLock: destroying locked QReadWriteLock");
188 if (
d ==
nullptr && d_ptr.testAndSetAcquire(
nullptr, dummyLockedForRead,
d))
198 if (!d_ptr.testAndSetAcquire(
nullptr, dummyLockedForRead,
d))
207 "Overflow in lock counter");
208 if (!d_ptr.testAndSetAcquire(
d,
val,
d))
213 if (
d == dummyLockedForWrite) {
219 val->writerCount = 1;
220 if (!d_ptr.testAndSetOrdered(
d,
val,
d)) {
221 val->writerCount = 0;
231 return d->recursiveLockForRead(
timeout);
233 auto lock = qt_unique_lock(
d->mutex);
234 if (
d != d_ptr.loadRelaxed()) {
241 d = d_ptr.loadAcquire();
303 if (
d ==
nullptr && d_ptr.testAndSetAcquire(
nullptr, dummyLockedForWrite,
d))
313 if (!d_ptr.testAndSetAcquire(
d, dummyLockedForWrite,
d))
318 if (isUncontendedLocked(
d)) {
324 if (
d == dummyLockedForWrite)
325 val->writerCount = 1;
328 if (!d_ptr.testAndSetOrdered(
d,
val,
d)) {
329 val->writerCount =
val->readerCount = 0;
339 return d->recursiveLockForWrite(
timeout);
341 auto lock = qt_unique_lock(
d->mutex);
342 if (
d != d_ptr.loadRelaxed()) {
346 d = d_ptr.loadAcquire();
361void QReadWriteLock::unlock()
365 Q_ASSERT_X(
d,
"QReadWriteLock::unlock()",
"Cannot unlock an unlocked lock");
369 if (!d_ptr.testAndSetOrdered(
d,
nullptr,
d))
378 if (!d_ptr.testAndSetOrdered(
d,
val,
d))
386 d->recursiveUnlock();
391 if (
d->writerCount) {
398 if (
d->readerCount > 0)
402 if (
d->waitingReaders ||
d->waitingWriters) {
406 d_ptr.storeRelease(
nullptr);
487 ++
it->recursionLevel;
531 qWarning(
"QReadWriteLock::unlock: unlocking from a thread that did not lock");
534 if (--
it->recursionLevel <= 0) {
550 enum { BlockCount = 4, MaxIndex=0xffff };
551 static const int Sizes[BlockCount];
554 QReadWriteLockFreeListConstants::Sizes[QReadWriteLockFreeListConstants::BlockCount] = {
555 16, 128, 1024, QReadWriteLockFreeListConstants::MaxIndex - (16 + 128 + 1024)
558typedef QFreeList<QReadWriteLockPrivate, QReadWriteLockFreeListConstants> QReadWriteLockFreeList;
564 int i = qrwl_freelist->next();
568 Q_ASSERT(!
d->waitingReaders && !
d->waitingWriters && !
d->readerCount && !
d->writerCount);
576 qrwl_freelist->release(
id);
std::condition_variable readerCond
bool lockForRead(std::unique_lock< std::mutex > &lock, QDeadlineTimer timeout)
bool lockForWrite(std::unique_lock< std::mutex > &lock, QDeadlineTimer timeout)
bool recursiveLockForRead(QDeadlineTimer timeout)
bool recursiveLockForWrite(QDeadlineTimer timeout)
static QReadWriteLockPrivate * allocate()
std::condition_variable writerCond
QVarLengthArray< Reader, 16 > currentReaders
static Qt::HANDLE currentThreadId() noexcept Q_DECL_PURE_FUNCTION
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Lock qt_scoped_lock(Mutex &mutex)
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
GLuint64 GLenum void * handle
GLbitfield GLuint64 timeout
[4]
#define Q_ASSERT_X(cond, x, msg)
static bool contendedTryLockForWrite(QAtomicPointer< QReadWriteLockPrivate > &d_ptr, QDeadlineTimer timeout, QReadWriteLockPrivate *d)
static bool contendedTryLockForRead(QAtomicPointer< QReadWriteLockPrivate > &d_ptr, QDeadlineTimer timeout, QReadWriteLockPrivate *d)
static auto handleEquals(Qt::HANDLE handle)