summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qbasicatomic.h6
-rw-r--r--src/corelib/thread/qexception.cpp2
-rw-r--r--src/corelib/thread/qfutureinterface.cpp2
-rw-r--r--src/corelib/thread/qmutex.cpp6
-rw-r--r--src/corelib/thread/qmutex_linux.cpp4
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h2
-rw-r--r--src/corelib/thread/qreadwritelock.cpp10
-rw-r--r--src/corelib/thread/qresultstore.cpp2
-rw-r--r--src/corelib/thread/qsemaphore.h7
-rw-r--r--src/corelib/thread/qthread.cpp36
-rw-r--r--src/corelib/thread/qthread.h8
-rw-r--r--src/corelib/thread/qthread_unix.cpp28
-rw-r--r--src/corelib/thread/qthread_win.cpp6
-rw-r--r--src/corelib/thread/qthreadpool.cpp2
-rw-r--r--src/corelib/thread/qthreadstorage.cpp12
-rw-r--r--src/corelib/thread/qwaitcondition.h39
-rw-r--r--src/corelib/thread/qwaitcondition.qdoc34
-rw-r--r--src/corelib/thread/qwaitcondition_p.h153
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp6
-rw-r--r--src/corelib/thread/thread.pri1
20 files changed, 279 insertions, 87 deletions
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 9804e60119..c9c95cf6ce 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -47,9 +47,9 @@
# include <QtCore/qatomic_bootstrap.h>
// If C++11 atomics are supported, use them!
-// Note that constexpr support is sometimes disabled in QNX builds but its
-// library has <atomic>.
-#elif defined(Q_COMPILER_ATOMICS) && (defined(Q_COMPILER_CONSTEXPR) || defined(Q_OS_QNX))
+// Note that constexpr support is sometimes disabled in QNX or INTEGRITY builds,
+// but their libraries have <atomic>.
+#elif defined(Q_COMPILER_ATOMICS) && (defined(Q_COMPILER_CONSTEXPR) || defined(Q_OS_QNX) || defined(Q_OS_INTEGRITY))
# include <QtCore/qatomic_cxx11.h>
// We only support one fallback: MSVC, because even on version 2015, it lacks full constexpr support
diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp
index a3e30d5a7a..f9c63085b7 100644
--- a/src/corelib/thread/qexception.cpp
+++ b/src/corelib/thread/qexception.cpp
@@ -199,7 +199,7 @@ void ExceptionStore::setException(const QException &e)
bool ExceptionStore::hasException() const
{
- return (exceptionHolder.exception() != 0);
+ return (exceptionHolder.exception() != nullptr);
}
ExceptionHolder ExceptionStore::exception()
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 6430f38a3b..f1fd40e7b6 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -471,7 +471,7 @@ bool QFutureInterfaceBase::derefT() const
QFutureInterfaceBasePrivate::QFutureInterfaceBasePrivate(QFutureInterfaceBase::State initialState)
: refCount(1), m_progressValue(0), m_progressMinimum(0), m_progressMaximum(0),
state(initialState),
- manualProgress(false), m_expectedResultCount(0), runnable(0), m_pool(0)
+ manualProgress(false), m_expectedResultCount(0), runnable(nullptr), m_pool(nullptr)
{
progressTime.invalidate();
}
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 9e52f286ee..f3883278e3 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -70,7 +70,7 @@ class QRecursiveMutexPrivate : public QMutexData
{
public:
QRecursiveMutexPrivate()
- : QMutexData(QMutex::Recursive), owner(0), count(0) {}
+ : QMutexData(QMutex::Recursive), owner(nullptr), count(0) {}
// written to by the thread that first owns 'mutex';
// read during attempts to acquire ownership of 'mutex' from any other thread:
@@ -186,7 +186,7 @@ public:
*/
QMutex::QMutex(RecursionMode mode)
{
- d_ptr.storeRelaxed(mode == Recursive ? new QRecursiveMutexPrivate : 0);
+ d_ptr.storeRelaxed(mode == Recursive ? new QRecursiveMutexPrivate : nullptr);
}
/*!
@@ -799,7 +799,7 @@ inline void QRecursiveMutexPrivate::unlock() noexcept
if (count > 0) {
count--;
} else {
- owner.storeRelaxed(0);
+ owner.storeRelaxed(nullptr);
mutex.QBasicMutex::unlock();
}
}
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
index 3270875471..72002838cf 100644
--- a/src/corelib/thread/qmutex_linux.cpp
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -106,7 +106,7 @@ static inline QMutexData *dummyFutexValue()
}
template <bool IsTimed> static inline
-bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1, QElapsedTimer *elapsedTimer = 0) noexcept
+bool lockInternal_helper(QBasicAtomicPointer<QMutexData> &d_ptr, int timeout = -1, QElapsedTimer *elapsedTimer = nullptr) noexcept
{
if (!IsTimed)
timeout = -1;
@@ -175,7 +175,7 @@ void QBasicMutex::unlockInternal() noexcept
Q_UNUSED(d);
Q_ASSERT(!isRecursive());
- d_ptr.storeRelease(0);
+ d_ptr.storeRelease(nullptr);
futexWakeOne(d_ptr);
}
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 570c526225..83edfd5879 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -69,7 +69,7 @@ class QOrderedMutexLocker
public:
QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2)
: mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
- mtx2((m1 == m2) ? 0 : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
+ mtx2((m1 == m2) ? nullptr : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
locked(false)
{
relock();
diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp
index 14654986a0..8c28507d5a 100644
--- a/src/corelib/thread/qreadwritelock.cpp
+++ b/src/corelib/thread/qreadwritelock.cpp
@@ -227,7 +227,7 @@ bool QReadWriteLock::tryLockForRead(int timeout)
return true;
while (true) {
- if (d == 0) {
+ if (d == nullptr) {
if (!d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d))
continue;
return true;
@@ -341,7 +341,7 @@ bool QReadWriteLock::tryLockForWrite(int timeout)
return true;
while (true) {
- if (d == 0) {
+ if (d == nullptr) {
if (!d_ptr.testAndSetAcquire(d, dummyLockedForWrite, d))
continue;
return true;
@@ -477,7 +477,7 @@ bool QReadWriteLockPrivate::lockForRead(int timeout)
if (elapsed > timeout)
return false;
waitingReaders++;
- readerCond.wait(&mutex, timeout - elapsed);
+ readerCond.wait(&mutex, QDeadlineTimer(timeout - elapsed));
} else {
waitingReaders++;
readerCond.wait(&mutex);
@@ -511,7 +511,7 @@ bool QReadWriteLockPrivate::lockForWrite(int timeout)
return false;
}
waitingWriters++;
- writerCond.wait(&mutex, timeout - elapsed);
+ writerCond.wait(&mutex, QDeadlineTimer(timeout - elapsed));
} else {
waitingWriters++;
writerCond.wait(&mutex);
@@ -581,7 +581,7 @@ void QReadWriteLockPrivate::recursiveUnlock()
if (self == currentWriter) {
if (--writerCount > 0)
return;
- currentWriter = 0;
+ currentWriter = nullptr;
} else {
auto it = currentReaders.find(self);
if (it == currentReaders.end()) {
diff --git a/src/corelib/thread/qresultstore.cpp b/src/corelib/thread/qresultstore.cpp
index 1b3bc20eca..0b82b938e1 100644
--- a/src/corelib/thread/qresultstore.cpp
+++ b/src/corelib/thread/qresultstore.cpp
@@ -192,7 +192,7 @@ int ResultStoreBase::addResults(int index, const void *results, int vectorSize,
ResultItem filteredIn(results, vectorSize);
insertResultItem(index, filteredIn);
}
- ResultItem filteredAway(0, totalCount - vectorSize);
+ ResultItem filteredAway(nullptr, totalCount - vectorSize);
return insertResultItem(index + vectorSize, filteredAway);
}
}
diff --git a/src/corelib/thread/qsemaphore.h b/src/corelib/thread/qsemaphore.h
index 58c12997ad..b3b9b52052 100644
--- a/src/corelib/thread/qsemaphore.h
+++ b/src/corelib/thread/qsemaphore.h
@@ -80,8 +80,7 @@ public:
explicit QSemaphoreReleaser(QSemaphore *sem, int n = 1) noexcept
: m_sem(sem), m_n(n) {}
QSemaphoreReleaser(QSemaphoreReleaser &&other) noexcept
- : m_sem(other.m_sem), m_n(other.m_n)
- { other.m_sem = nullptr; }
+ : m_sem(other.cancel()), m_n(other.m_n) {}
QSemaphoreReleaser &operator=(QSemaphoreReleaser &&other) noexcept
{ QSemaphoreReleaser moved(std::move(other)); swap(moved); return *this; }
@@ -102,9 +101,7 @@ public:
QSemaphore *cancel() noexcept
{
- QSemaphore *old = m_sem;
- m_sem = nullptr;
- return old;
+ return qExchange(m_sem, nullptr);
}
private:
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 880ae9e046..d3bb372b00 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -49,6 +49,8 @@
#include "qthread_p.h"
#include "private/qcoreapplication_p.h"
+#include <limits>
+
QT_BEGIN_NAMESPACE
/*
@@ -57,7 +59,7 @@ QT_BEGIN_NAMESPACE
QThreadData::QThreadData(int initialRefCount)
: _ref(initialRefCount), loopLevel(0), scopeLevel(0),
- eventDispatcher(0),
+ eventDispatcher(nullptr),
quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true)
{
// fprintf(stderr, "QThreadData %p created\n", this);
@@ -397,7 +399,7 @@ QThreadPrivate::~QThreadPrivate()
QThread *QThread::currentThread()
{
QThreadData *data = QThreadData::current();
- Q_ASSERT(data != 0);
+ Q_ASSERT(data != nullptr);
return data->thread.loadAcquire();
}
@@ -449,7 +451,7 @@ QThread::~QThread()
if (d->running && !d->finished && !d->data->isAdopted)
qFatal("QThread: Destroyed while thread is still running");
- d->data->thread = 0;
+ d->data->thread = nullptr;
}
}
@@ -726,7 +728,8 @@ QThread::Priority QThread::priority() const
*/
/*!
- \fn bool QThread::wait(unsigned long time)
+ \fn bool QThread::wait(QDeadlineTimer deadline)
+ \since 5.15
Blocks the thread until either of these conditions is met:
@@ -735,12 +738,14 @@ QThread::Priority QThread::priority() const
execution (i.e. when it returns from \l{run()}). This function
will return true if the thread has finished. It also returns
true if the thread has not been started yet.
- \li \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
- default), then the wait will never timeout (the thread must
- return from \l{run()}). This function will return false if the
- wait timed out.
+ \li The \a deadline is reached. This function will return false if the
+ deadline is reached.
\endlist
+ A deadline timer set to \c QDeadlineTimer::Forever (the default) will never
+ time out: in this case, the function only returns when the thread returns
+ from \l{run()} or if the thread has not yet started.
+
This provides similar functionality to the POSIX \c
pthread_join() function.
@@ -833,9 +838,9 @@ void QThread::exit(int returnCode)
}
}
-bool QThread::wait(unsigned long time)
+bool QThread::wait(QDeadlineTimer deadline)
{
- Q_UNUSED(time);
+ Q_UNUSED(deadline);
return false;
}
@@ -966,6 +971,17 @@ void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
}
}
+/*!
+ \fn bool QThread::wait(unsigned long time)
+ \overload
+*/
+bool QThread::wait(unsigned long time)
+{
+ if (time == std::numeric_limits<unsigned long>::max())
+ return wait(QDeadlineTimer(QDeadlineTimer::Forever));
+ return wait(QDeadlineTimer(time));
+}
+
#if QT_CONFIG(thread)
/*!
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index c7a6dc8f1a..2072e22340 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -42,6 +42,7 @@
#define QTHREAD_H
#include <QtCore/qobject.h>
+#include <QtCore/qdeadlinetimer.h>
// For QThread::create. The configure-time test just checks for the availability
// of std::future and std::async; for the C++17 codepath we perform some extra
@@ -57,8 +58,6 @@
# endif
#endif
-#include <limits.h>
-
QT_BEGIN_NAMESPACE
@@ -135,8 +134,9 @@ public Q_SLOTS:
void quit();
public:
- // default argument causes thread to block indefinetely
- bool wait(unsigned long time = ULONG_MAX);
+ bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever));
+ // ### Qt6 inline this function
+ bool wait(unsigned long time);
static void sleep(unsigned long);
static void msleep(unsigned long);
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index cb3c0d6bb1..1da68b3130 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -109,7 +109,7 @@ Q_STATIC_ASSERT(sizeof(pthread_t) <= sizeof(Qt::HANDLE));
enum { ThreadPriorityResetFlag = 0x80000000 };
-static thread_local QThreadData *currentThreadData = 0;
+static thread_local QThreadData *currentThreadData = nullptr;
static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT;
static pthread_key_t current_thread_data_key;
@@ -144,7 +144,7 @@ static void destroy_current_thread_data(void *p)
#if defined(Q_OS_VXWORKS)
(void *)1);
#else
- 0);
+ nullptr);
#endif
}
@@ -182,8 +182,8 @@ static void set_thread_data(QThreadData *data)
static void clear_thread_data()
{
- currentThreadData = 0;
- pthread_setspecific(current_thread_data_key, 0);
+ currentThreadData = nullptr;
+ pthread_setspecific(current_thread_data_key, nullptr);
}
template <typename T>
@@ -226,7 +226,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
} QT_CATCH(...) {
clear_thread_data();
data->deref();
- data = 0;
+ data = nullptr;
QT_RETHROW;
}
data->deref();
@@ -294,7 +294,7 @@ static void setCurrentThreadName(const char *name)
void *QThreadPrivate::start(void *arg)
{
#if !defined(Q_OS_ANDROID)
- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
#endif
pthread_cleanup_push(QThreadPrivate::finish, arg);
@@ -336,7 +336,7 @@ void *QThreadPrivate::start(void *arg)
emit thr->started(QThread::QPrivateSignal());
#if !defined(Q_OS_ANDROID)
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
pthread_testcancel();
#endif
thr->run();
@@ -360,7 +360,7 @@ void *QThreadPrivate::start(void *arg)
// thrown.
pthread_cleanup_pop(1);
- return 0;
+ return nullptr;
}
void QThreadPrivate::finish(void *arg)
@@ -379,13 +379,13 @@ void QThreadPrivate::finish(void *arg)
void *data = &d->data->tls;
locker.unlock();
emit thr->finished(QThread::QPrivateSignal());
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
QThreadStorageData::finish((void **)data);
locker.relock();
QAbstractEventDispatcher *eventDispatcher = d->data->eventDispatcher.loadRelaxed();
if (eventDispatcher) {
- d->data->eventDispatcher = 0;
+ d->data->eventDispatcher = nullptr;
locker.unlock();
eventDispatcher->closingDown();
delete eventDispatcher;
@@ -751,7 +751,7 @@ void QThread::terminate()
#endif
}
-bool QThread::wait(unsigned long time)
+bool QThread::wait(QDeadlineTimer deadline)
{
Q_D(QThread);
QMutexLocker locker(&d->mutex);
@@ -765,7 +765,7 @@ bool QThread::wait(unsigned long time)
return true;
while (d->running) {
- if (!d->thread_done.wait(locker.mutex(), time))
+ if (!d->thread_done.wait(locker.mutex(), deadline))
return false;
}
return true;
@@ -774,14 +774,14 @@ bool QThread::wait(unsigned long time)
void QThread::setTerminationEnabled(bool enabled)
{
QThread *thr = currentThread();
- Q_ASSERT_X(thr != 0, "QThread::setTerminationEnabled()",
+ Q_ASSERT_X(thr != nullptr, "QThread::setTerminationEnabled()",
"Current thread was not started with QThread.");
Q_UNUSED(thr)
#if defined(Q_OS_ANDROID)
Q_UNUSED(enabled);
#else
- pthread_setcancelstate(enabled ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE, NULL);
+ pthread_setcancelstate(enabled ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE, nullptr);
if (enabled)
pthread_testcancel();
#endif
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index a72df2fc40..3df7080caf 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -610,7 +610,7 @@ void QThread::terminate()
QThreadPrivate::finish(this, false);
}
-bool QThread::wait(unsigned long time)
+bool QThread::wait(QDeadlineTimer deadline)
{
Q_D(QThread);
QMutexLocker locker(&d->mutex);
@@ -627,9 +627,9 @@ bool QThread::wait(unsigned long time)
bool ret = false;
#ifndef Q_OS_WINRT
- switch (WaitForSingleObject(d->handle, time)) {
+ switch (WaitForSingleObject(d->handle, deadline.remainingTime())) {
#else
- switch (WaitForSingleObjectEx(d->handle, time, false)) {
+ switch (WaitForSingleObjectEx(d->handle, deadline.remainingTime(), false)) {
#endif
case WAIT_OBJECT_0:
ret = true;
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 4d2389f699..5f23a78c8a 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -136,7 +136,7 @@ void QThreadPoolThread::run()
manager->waitingThreads.enqueue(this);
registerThreadInactive();
// wait for work, exiting after the expiry timeout is reached
- runnableReady.wait(locker.mutex(), manager->expiryTimeout);
+ runnableReady.wait(locker.mutex(), QDeadlineTimer(manager->expiryTimeout));
++manager->activeThreads;
if (manager->waitingThreads.removeOne(this))
expired = true;
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index fdc484d2d2..464559ffa5 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -116,7 +116,7 @@ void **QThreadStorageData::get() const
QThreadData *data = QThreadData::current();
if (!data) {
qWarning("QThreadStorage::get: QThreadStorage can only be used with threads started with QThread");
- return 0;
+ return nullptr;
}
QVector<void *> &tls = data->tls;
if (tls.size() <= id)
@@ -128,7 +128,7 @@ void **QThreadStorageData::get() const
*v,
data->thread.loadRelaxed());
- return *v ? v : 0;
+ return *v ? v : nullptr;
}
void **QThreadStorageData::set(void *p)
@@ -136,7 +136,7 @@ void **QThreadStorageData::set(void *p)
QThreadData *data = QThreadData::current();
if (!data) {
qWarning("QThreadStorage::set: QThreadStorage can only be used with threads started with QThread");
- return 0;
+ return nullptr;
}
QVector<void *> &tls = data->tls;
if (tls.size() <= id)
@@ -144,7 +144,7 @@ void **QThreadStorageData::set(void *p)
void *&value = tls[id];
// delete any previous data
- if (value != 0) {
+ if (value != nullptr) {
DEBUG_MSG("QThreadStorageData: Deleting previous storage %d, data %p, for thread %p",
id,
value,
@@ -156,7 +156,7 @@ void **QThreadStorageData::set(void *p)
locker.unlock();
void *q = value;
- value = 0;
+ value = nullptr;
if (destructor)
destructor(q);
@@ -178,7 +178,7 @@ void QThreadStorageData::finish(void **p)
while (!tls->isEmpty()) {
void *&value = tls->last();
void *q = value;
- value = 0;
+ value = nullptr;
int i = tls->size() - 1;
tls->resize(i);
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index 11520e4cfe..079049af25 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -40,15 +40,12 @@
#ifndef QWAITCONDITION_H
#define QWAITCONDITION_H
-#include <QtCore/qglobal.h>
-
-#include <limits.h>
+#include <QtCore/QDeadlineTimer>
QT_BEGIN_NAMESPACE
#if QT_CONFIG(thread)
-class QDeadlineTimer;
class QWaitConditionPrivate;
class QMutex;
class QReadWriteLock;
@@ -59,11 +56,16 @@ public:
QWaitCondition();
~QWaitCondition();
- // ### Qt 6: remove unsigned long overloads
- bool wait(QMutex *lockedMutex, unsigned long time = ULONG_MAX);
- bool wait(QMutex *lockedMutex, QDeadlineTimer deadline);
- bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time = ULONG_MAX);
- bool wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline);
+ bool wait(QMutex *lockedMutex,
+ QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever));
+ bool wait(QReadWriteLock *lockedReadWriteLock,
+ QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever));
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_VERSION_X_5_15("Use wait(QMutex *lockedMutex, QDeadlineTimer deadline) instead")
+ bool wait(QMutex *lockedMutex, unsigned long time);
+ QT_DEPRECATED_VERSION_X_5_15("Use wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline) instead")
+ bool wait(QReadWriteLock *lockedReadWriteLock, unsigned long time);
+#endif
void wakeOne();
void wakeAll();
@@ -80,21 +82,28 @@ private:
#else
class QMutex;
+class QReadWriteLock;
+
class Q_CORE_EXPORT QWaitCondition
{
public:
QWaitCondition() {}
~QWaitCondition() {}
- bool wait(QMutex *mutex, unsigned long time = ULONG_MAX)
- {
- Q_UNUSED(mutex);
- Q_UNUSED(time);
- return true;
- }
+ bool wait(QMutex *, QDeadlineTimer = QDeadlineTimer(QDeadlineTimer::Forever))
+ { return true; }
+ bool wait(QReadWriteLock *, QDeadlineTimer = QDeadlineTimer(QDeadlineTimer::Forever))
+ { return true; }
+#if QT_DEPRECATED_SINCE(5, 15)
+ bool wait(QMutex *, unsigned long) { return true; }
+ bool wait(QReadWriteLock *, unsigned long) { return true; }
+#endif
void wakeOne() {}
void wakeAll() {}
+
+ void notify_one() { wakeOne(); }
+ void notify_all() { wakeAll(); }
};
#endif // QT_CONFIG(thread)
diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc
index eebc28f059..9da6f6f25c 100644
--- a/src/corelib/thread/qwaitcondition.qdoc
+++ b/src/corelib/thread/qwaitcondition.qdoc
@@ -119,10 +119,22 @@
\sa wakeOne()
*/
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn bool QWaitCondition::wait(QMutex *lockedMutex, unsigned long time)
+ \obsolete use wait(QMutex *lockedMutex, QDeadlineTimer deadline) instead
+*/
+/*!
+ \fn bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time)
+ \obsolete use wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline) instead
+*/
+#endif
- Releases the \a lockedMutex and waits on the wait condition. The
+/*!
+ \fn bool QWaitCondition::wait(QMutex *lockedMutex, QDeadlineTimer deadline)
+ \since 5.12
+
+ Releases the \a lockedMutex and waits on the wait condition. The
\a lockedMutex must be initially locked by the calling thread. If \a
lockedMutex is not in a locked state, the behavior is undefined. If
\a lockedMutex is a recursive mutex, this function
@@ -132,10 +144,10 @@
\list
\li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
- (the default), then the wait will never timeout (the event
- must be signalled). This function will return false if the
- wait timed out.
+ \li the deadline given by \a deadline is reached. If \a deadline is
+ \c QDeadlineTimer::Forever (the default), then the wait will never
+ timeout (the event must be signalled). This function will return
+ false if the wait timed out.
\endlist
The \a lockedMutex will be returned to the same locked state. This
@@ -146,8 +158,8 @@
*/
/*!
- \fn bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, unsigned long time)
- \since 4.4
+ \fn bool QWaitCondition::wait(QReadWriteLock *lockedReadWriteLock, QDeadlineTimer deadline)
+ \since 5.12
Releases the \a lockedReadWriteLock and waits on the wait
condition. The \a lockedReadWriteLock must be initially locked by the
@@ -160,10 +172,10 @@
\list
\li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
- (the default), then the wait will never timeout (the event
- must be signalled). This function will return false if the
- wait timed out.
+ \li the deadline given by \a deadline is reached. If \a deadline is
+ \c QDeadlineTimer::Forever (the default), then the wait will never
+ timeout (the event must be signalled). This function will return
+ false if the wait timed out.
\endlist
The \a lockedReadWriteLock will be returned to the same locked
diff --git a/src/corelib/thread/qwaitcondition_p.h b/src/corelib/thread/qwaitcondition_p.h
new file mode 100644
index 0000000000..5133e52e92
--- /dev/null
+++ b/src/corelib/thread/qwaitcondition_p.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QWAITCONDITION_P_H
+#define QWAITCONDITION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qmutex.cpp, qmutex_unix.cpp, and qmutex_win.cpp. This header
+// file may change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QWaitCondition>
+#include <QtCore/QMutex>
+#include <QtCore/QDeadlineTimer>
+
+#include <condition_variable>
+#include <mutex>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtPrivate
+{
+
+#if defined(Q_OS_INTEGRITY)
+
+class condition_variable;
+
+class mutex : private QMutex
+{
+ friend class QtPrivate::condition_variable;
+public:
+ // all special member functions are ok!
+ // do not expose the (QMutex::Recursive) ctor
+ // don't use 'using QMutex::lock;' etc as those have the wrong noexcept
+
+ void lock() { return QMutex::lock(); }
+ void unlock() { return QMutex::unlock(); }
+ bool try_lock() { return QMutex::tryLock(); }
+};
+
+class condition_variable : private QWaitCondition
+{
+public:
+ // all special member functions are ok!
+
+ void notify_one() { QWaitCondition::wakeOne(); }
+ void notify_all() { QWaitCondition::wakeAll(); }
+
+ void wait(std::unique_lock<QtPrivate::mutex> &lock) { QWaitCondition::wait(lock.mutex()); }
+ template <class Predicate>
+ void wait(std::unique_lock<QtPrivate::mutex> &lock, Predicate p)
+ {
+ while (!p())
+ wait(lock);
+ }
+
+ template <typename Rep, typename Period>
+ std::cv_status wait_for(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::duration<Rep, Period> &d)
+ {
+ return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{d})
+ ? std::cv_status::no_timeout
+ : std::cv_status::timeout;
+ }
+ template <typename Rep, typename Period, typename Predicate>
+ bool wait_for(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::duration<Rep, Period> &d, Predicate p)
+ {
+ const auto timer = QDeadlineTimer{d};
+ while (!p()) {
+ if (!QWaitCondition::wait(lock.mutex(), timer))
+ return p();
+ }
+ return true;
+ }
+
+ template <typename Clock, typename Duration>
+ std::cv_status wait_until(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::time_point<Clock, Duration> &t)
+ {
+ return QWaitCondition::wait(lock.mutex(), QDeadlineTimer{t})
+ ? std::cv_status::no_timeout
+ : std::cv_status::timeout;
+ }
+
+ template <typename Clock, typename Duration, typename Predicate>
+ bool wait_until(std::unique_lock<QtPrivate::mutex> &lock,
+ const std::chrono::time_point<Clock, Duration> &t, Predicate p)
+ {
+ const auto timer = QDeadlineTimer{t};
+ while (!p()) {
+ if (!QWaitCondition::wait(lock.mutex(), timer))
+ return p();
+ }
+ return true;
+ }
+
+};
+
+#else // Integrity
+
+using mutex = std::mutex;
+using condition_variable = std::condition_variable;
+
+#endif // Integrity
+
+} // namespace QtPrivate
+
+QT_END_NAMESPACE
+
+#endif /* QWAITCONDITION_P_H */
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index dd7475cec5..80f9e780e7 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -173,7 +173,7 @@ public:
QWaitCondition::QWaitCondition()
{
d = new QWaitConditionPrivate;
- report_error(pthread_mutex_init(&d->mutex, NULL), "QWaitCondition", "mutex init");
+ report_error(pthread_mutex_init(&d->mutex, nullptr), "QWaitCondition", "mutex init");
qt_initialize_pthread_cond(&d->cond, "QWaitCondition");
d->waiters = d->wakeups = 0;
}
@@ -202,12 +202,14 @@ void QWaitCondition::wakeAll()
report_error(pthread_mutex_unlock(&d->mutex), "QWaitCondition::wakeAll()", "mutex unlock");
}
+#if QT_DEPRECATED_SINCE(5, 15)
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
if (time == std::numeric_limits<unsigned long>::max())
return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
return wait(mutex, QDeadlineTimer(time));
}
+#endif
bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
{
@@ -229,12 +231,14 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
return returnValue;
}
+#if QT_DEPRECATED_SINCE(5, 15)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
if (time == std::numeric_limits<unsigned long>::max())
return wait(readWriteLock, QDeadlineTimer(QDeadlineTimer::Forever));
return wait(readWriteLock, QDeadlineTimer(time));
}
+#endif
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
{
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index 9fc9af0e65..25cf68a324 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -6,6 +6,7 @@ HEADERS += \
thread/qrunnable.h \
thread/qthread.h \
thread/qthreadstorage.h \
+ thread/qwaitcondition_p.h \
thread/qwaitcondition.h
SOURCES += \