diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-08-06 10:45:40 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-08-06 10:54:01 +0200 |
commit | 77da617dc8e378a631ee8c15b1b414f16b87f147 (patch) | |
tree | 563f4f8e64e416774ea2b1599b896b589385168c /src/corelib/thread | |
parent | c17134e2db4d364855aa78a0d3c47cb9ef964dd9 (diff) | |
parent | 01f3530650f9f6f4c08520263a3c62281d81e3fc (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
doc/global/qt-cpp-defines.qdocconf
src/3rdparty/forkfd/forkfd.c
src/corelib/codecs/qtextcodec.cpp
src/corelib/kernel/qmetatype.cpp
src/corelib/tools/qset.qdoc
src/gui/accessible/qaccessible.cpp
src/gui/image/qpixmapcache.cpp
src/opengl/qgl.cpp
src/tools/qdoc/generator.cpp
src/widgets/kernel/qwidget.cpp
tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
Change-Id: I4fbe1fa756a54c6843aa75f4ef70a1069ba7b085
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qreadwritelock.cpp | 57 | ||||
-rw-r--r-- | src/corelib/thread/qreadwritelock_p.h | 1 |
2 files changed, 58 insertions, 0 deletions
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index e6477bf5e0..0ea8c4c00f 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -136,11 +136,27 @@ void QReadWriteLock::lockForRead() { QMutexLocker lock(&d->mutex); + Qt::HANDLE self = 0; + if (d->recursive) { + self = QThread::currentThreadId(); + + QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self); + if (it != d->currentReaders.end()) { + ++it.value(); + ++d->accessCount; + Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", + "Overflow in lock counter"); + return; + } + } + while (d->accessCount < 0 || d->waitingWriters) { ++d->waitingReaders; d->readerWait.wait(&d->mutex); --d->waitingReaders; } + if (d->recursive) + d->currentReaders.insert(self, 1); ++d->accessCount; Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::lockForRead()", "Overflow in lock counter"); @@ -166,8 +182,24 @@ bool QReadWriteLock::tryLockForRead() { QMutexLocker lock(&d->mutex); + Qt::HANDLE self = 0; + if (d->recursive) { + self = QThread::currentThreadId(); + + QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self); + if (it != d->currentReaders.end()) { + ++it.value(); + ++d->accessCount; + Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", + "Overflow in lock counter"); + return true; + } + } + if (d->accessCount < 0) return false; + if (d->recursive) + d->currentReaders.insert(self, 1); ++d->accessCount; Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter"); @@ -198,6 +230,20 @@ bool QReadWriteLock::tryLockForRead(int timeout) { QMutexLocker lock(&d->mutex); + Qt::HANDLE self = 0; + if (d->recursive) { + self = QThread::currentThreadId(); + + QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self); + if (it != d->currentReaders.end()) { + ++it.value(); + ++d->accessCount; + Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", + "Overflow in lock counter"); + return true; + } + } + while (d->accessCount < 0 || d->waitingWriters) { ++d->waitingReaders; bool success = d->readerWait.wait(&d->mutex, timeout < 0 ? ULONG_MAX : ulong(timeout)); @@ -205,6 +251,8 @@ bool QReadWriteLock::tryLockForRead(int timeout) if (!success) return false; } + if (d->recursive) + d->currentReaders.insert(self, 1); ++d->accessCount; Q_ASSERT_X(d->accessCount > 0, "QReadWriteLock::tryLockForRead()", "Overflow in lock counter"); @@ -364,6 +412,15 @@ void QReadWriteLock::unlock() bool unlocked = false; if (d->accessCount > 0) { // releasing a read lock + if (d->recursive) { + Qt::HANDLE self = QThread::currentThreadId(); + QHash<Qt::HANDLE, int>::iterator it = d->currentReaders.find(self); + if (it != d->currentReaders.end()) { + if (--it.value() <= 0) + d->currentReaders.erase(it); + } + } + unlocked = --d->accessCount == 0; } else if (d->accessCount < 0 && ++d->accessCount == 0) { // released a write lock diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h index 15a6d1f57e..e57c0e403f 100644 --- a/src/corelib/thread/qreadwritelock_p.h +++ b/src/corelib/thread/qreadwritelock_p.h @@ -69,6 +69,7 @@ struct QReadWriteLockPrivate bool recursive; Qt::HANDLE currentWriter; + QHash<Qt::HANDLE, int> currentReaders; }; QT_END_NAMESPACE |