6#include "qplatformdefs.h"
12#include "private/qfreelist_p.h"
13#include "private/qlocking_p.h"
34using steady_clock = std::chrono::steady_clock;
129 if (isUncontendedLocked(
d)) {
130 qWarning(
"QReadWriteLock: destroying locked QReadWriteLock");
189 if (
d ==
nullptr && d_ptr.testAndSetAcquire(
nullptr, dummyLockedForRead,
d))
208 "Overflow in lock counter");
214 if (
d == dummyLockedForWrite) {
220 val->writerCount = 1;
222 val->writerCount = 0;
232 return d->recursiveLockForRead(
timeout);
234 auto lock = qt_unique_lock(
d->mutex);
304 if (
d ==
nullptr && d_ptr.testAndSetAcquire(
nullptr, dummyLockedForWrite,
d))
319 if (isUncontendedLocked(
d)) {
325 if (
d == dummyLockedForWrite)
326 val->writerCount = 1;
330 val->writerCount =
val->readerCount = 0;
340 return d->recursiveLockForWrite(
timeout);
342 auto lock = qt_unique_lock(
d->mutex);
362void QReadWriteLock::unlock()
366 Q_ASSERT_X(
d,
"QReadWriteLock::unlock()",
"Cannot unlock an unlocked lock");
370 if (!d_ptr.testAndSetOrdered(
d,
nullptr,
d))
379 if (!d_ptr.testAndSetOrdered(
d,
val,
d))
387 d->recursiveUnlock();
392 if (
d->writerCount) {
399 if (
d->readerCount > 0)
403 if (
d->waitingReaders ||
d->waitingWriters) {
407 d_ptr.storeRelease(
nullptr);
488 ++
it->recursionLevel;
532 qWarning(
"QReadWriteLock::unlock: unlocking from a thread that did not lock");
535 if (--
it->recursionLevel <= 0) {
551 enum { BlockCount = 4, MaxIndex=0xffff };
555 QReadWriteLockFreeListConstants::Sizes[QReadWriteLockFreeListConstants::BlockCount] = {
556 16, 128, 1024, QReadWriteLockFreeListConstants::MaxIndex - (16 + 128 + 1024)
565 int i = qrwl_freelist->next();
569 Q_ASSERT(!
d->waitingReaders && !
d->waitingWriters && !
d->readerCount && !
d->writerCount);
577 qrwl_freelist->release(
id);
\macro Q_ATOMIC_INTnn_IS_SUPPORTED
bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept
Type loadAcquire() const noexcept
bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept
Type loadRelaxed() const noexcept
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)