summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:45:40 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:54:01 +0200
commit77da617dc8e378a631ee8c15b1b414f16b87f147 (patch)
tree563f4f8e64e416774ea2b1599b896b589385168c /src/corelib/thread
parentc17134e2db4d364855aa78a0d3c47cb9ef964dd9 (diff)
parent01f3530650f9f6f4c08520263a3c62281d81e3fc (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.cpp57
-rw-r--r--src/corelib/thread/qreadwritelock_p.h1
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