summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qfuture.h1
-rw-r--r--src/corelib/thread/qfutureinterface.h2
-rw-r--r--src/corelib/thread/qmutex_p.h3
-rw-r--r--src/corelib/thread/qmutex_unix.cpp2
-rw-r--r--src/corelib/thread/qreadwritelock_p.h2
-rw-r--r--src/corelib/thread/qsemaphore.cpp6
-rw-r--r--src/corelib/thread/qthread.cpp48
-rw-r--r--src/corelib/thread/qthread.h7
-rw-r--r--src/corelib/thread/qthread_p.h17
-rw-r--r--src/corelib/thread/qthread_unix.cpp12
-rw-r--r--src/corelib/thread/qthread_win.cpp18
-rw-r--r--src/corelib/thread/qwaitcondition.h4
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp53
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp11
14 files changed, 133 insertions, 53 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index af599c26db..a456dd9139 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -136,6 +136,7 @@ public:
inline const_iterator operator-(int j) const { return const_iterator(future, index - j); }
inline const_iterator &operator+=(int j) { index += j; return *this; }
inline const_iterator &operator-=(int j) { index -= j; return *this; }
+ friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
private:
QFuture const * future;
int index;
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 3dd236752c..d5e2401eee 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -178,7 +178,7 @@ public:
inline void reportResult(const T *result, int index = -1);
inline void reportResult(const T &result, int index = -1);
inline void reportResults(const QVector<T> &results, int beginIndex = -1, int count = -1);
- inline void reportFinished(const T *result = 0);
+ inline void reportFinished(const T *result = nullptr);
inline const T &resultReference(int index) const;
inline const T *resultPointer(int index) const;
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index 4e6f522a37..ec9bfc1152 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -58,6 +58,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qmutex.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qdeadlinetimer.h>
#if defined(Q_OS_MAC)
# include <mach/semaphore.h>
@@ -146,7 +147,7 @@ public:
// helper functions for qmutex_unix.cpp and qwaitcondition_unix.cpp
// they are in qwaitcondition_unix.cpp actually
void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where);
-void qt_abstime_for_timeout(struct timespec *ts, int timeout);
+void qt_abstime_for_timeout(struct timespec *ts, QDeadlineTimer deadline);
#endif
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 3e1e531be4..91f02ba3ec 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -130,7 +130,7 @@ bool QMutexPrivate::wait(int timeout)
errorCode = pthread_cond_wait(&cond, &mutex);
} else {
timespec ti;
- qt_abstime_for_timeout(&ti, timeout);
+ qt_abstime_for_timeout(&ti, QDeadlineTimer(timeout));
errorCode = pthread_cond_timedwait(&cond, &mutex, &ti);
}
if (errorCode) {
diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h
index 04dd45a2e1..a01d010043 100644
--- a/src/corelib/thread/qreadwritelock_p.h
+++ b/src/corelib/thread/qreadwritelock_p.h
@@ -54,7 +54,7 @@
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qhash.h>
-#include <QtCore/QWaitCondition>
+#include <QtCore/qwaitcondition.h>
#ifndef QT_NO_THREAD
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 74e0746f43..82d439a728 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -487,11 +487,9 @@ bool QSemaphore::tryAcquire(int n, int timeout)
QDeadlineTimer timer(timeout);
QMutexLocker locker(&d->mutex);
- qint64 remainingTime = timer.remainingTime();
- while (n > d->avail && remainingTime != 0) {
- if (!d->cond.wait(locker.mutex(), remainingTime))
+ while (n > d->avail && !timer.hasExpired()) {
+ if (!d->cond.wait(locker.mutex(), timer))
return false;
- remainingTime = timer.remainingTime();
}
if (n > d->avail)
return false;
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 23606411ff..472c6f6795 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -117,6 +117,14 @@ void QThreadData::deref()
#endif
}
+QAbstractEventDispatcher *QThreadData::createEventDispatcher()
+{
+ QAbstractEventDispatcher *ed = QThreadPrivate::createEventDispatcher(this);
+ eventDispatcher.storeRelease(ed);
+ ed->startingUp();
+ return ed;
+}
+
/*
QAdoptedThread
*/
@@ -140,12 +148,13 @@ QAdoptedThread::~QAdoptedThread()
// fprintf(stderr, "~QAdoptedThread = %p\n", this);
}
+#ifndef QT_NO_THREAD
void QAdoptedThread::run()
{
// this function should never be called
qFatal("QAdoptedThread::run(): Internal error, this implementation should never be called.");
}
-#ifndef QT_NO_THREAD
+
/*
QThreadPrivate
*/
@@ -750,7 +759,8 @@ int QThread::loopLevel() const
#else // QT_NO_THREAD
QThread::QThread(QObject *parent)
- : QObject(*(new QThreadPrivate), (QObject*)0){
+ : QObject(*(new QThreadPrivate), parent)
+{
Q_D(QThread);
d->data->thread = this;
}
@@ -760,18 +770,27 @@ QThread *QThread::currentThread()
return QThreadData::current()->thread;
}
-QThreadData* QThreadData::current()
+// No threads: so we can just use static variables
+static QThreadData *data = 0;
+
+QThreadData *QThreadData::current(bool createIfNecessary)
{
- static QThreadData *data = 0; // reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
- if (!data) {
- QScopedPointer<QThreadData> newdata(new QThreadData);
- newdata->thread = new QAdoptedThread(newdata.data());
- data = newdata.take();
+ if (!data && createIfNecessary) {
+ data = new QThreadData;
+ data->thread = new QAdoptedThread(data);
data->deref();
+ if (!QCoreApplicationPrivate::theMainThread)
+ QCoreApplicationPrivate::theMainThread = data->thread.load();
}
return data;
}
+void QThreadData::clearCurrentThreadData()
+{
+ delete data;
+ data = 0;
+}
+
/*!
\internal
*/
@@ -783,6 +802,15 @@ QThread::QThread(QThreadPrivate &dd, QObject *parent)
d->data->thread = this;
}
+QThreadPrivate::QThreadPrivate(QThreadData *d) : data(d ? d : new QThreadData)
+{
+}
+
+QThreadPrivate::~QThreadPrivate()
+{
+ delete data;
+}
+
#endif // QT_NO_THREAD
/*!
@@ -820,6 +848,8 @@ void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
}
}
+#ifndef QT_NO_THREAD
+
/*!
\reimp
*/
@@ -983,6 +1013,8 @@ QDaemonThread::~QDaemonThread()
{
}
+#endif // QT_NO_THREAD
+
QT_END_NAMESPACE
#include "moc_qthread.cpp"
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index 3df76077e1..83c3329cc0 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -247,6 +247,13 @@ public:
static Qt::HANDLE currentThreadId() { return Qt::HANDLE(currentThread()); }
static QThread* currentThread();
+ static void sleep(unsigned long);
+ static void msleep(unsigned long);
+ static void usleep(unsigned long);
+
+ QAbstractEventDispatcher *eventDispatcher() const;
+ void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
+
protected:
QThread(QThreadPrivate &dd, QObject *parent = nullptr);
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index 46294a5fc8..93f245ff6e 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -215,9 +215,10 @@ public:
class QThreadPrivate : public QObjectPrivate
{
public:
- QThreadPrivate(QThreadData *d = 0) : data(d ? d : new QThreadData) {}
- ~QThreadPrivate() { delete data; }
+ QThreadPrivate(QThreadData *d = 0);
+ ~QThreadPrivate();
+ mutable QMutex mutex;
QThreadData *data;
static void setCurrentThread(QThread*) {}
@@ -247,7 +248,15 @@ public:
void ref();
void deref();
inline bool hasEventDispatcher() const
- { return eventDispatcher.load() != 0; }
+ { return eventDispatcher.load() != nullptr; }
+ QAbstractEventDispatcher *createEventDispatcher();
+ QAbstractEventDispatcher *ensureEventDispatcher()
+ {
+ QAbstractEventDispatcher *ed = eventDispatcher.load();
+ if (Q_LIKELY(ed))
+ return ed;
+ return createEventDispatcher();
+ }
bool canWaitLocked()
{
@@ -318,7 +327,9 @@ public:
void init();
private:
+#ifndef QT_NO_THREAD
void run() override;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 9ad32b162d..0b3c7ddf10 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -339,13 +339,7 @@ void *QThreadPrivate::start(void *arg)
data->quitNow = thr->d_func()->exited;
}
- QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
- if (!eventDispatcher) {
- eventDispatcher = createEventDispatcher(data);
- data->eventDispatcher.storeRelease(eventDispatcher);
- }
-
- eventDispatcher->startingUp();
+ data->ensureEventDispatcher();
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
{
@@ -519,6 +513,8 @@ void QThread::yieldCurrentThread()
sched_yield();
}
+#endif // QT_NO_THREAD
+
static timespec makeTimespec(time_t secs, long nsecs)
{
struct timespec ts;
@@ -542,6 +538,8 @@ void QThread::usleep(unsigned long usecs)
qt_nanosleep(makeTimespec(usecs / 1000 / 1000, usecs % (1000*1000) * 1000));
}
+#ifndef QT_NO_THREAD
+
#ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING
#if defined(Q_OS_QNX)
static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 4459ae87af..83bcb7d751 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -61,9 +61,10 @@
# include <process.h>
#endif // Q_OS_WINRT
-#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_THREAD
+
#ifdef Q_OS_WINRT
inline DWORD qWinRTTlsAlloc() {
return FlsAlloc(0);
@@ -359,13 +360,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
data->quitNow = thr->d_func()->exited;
}
- QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
- if (!eventDispatcher) {
- eventDispatcher = createEventDispatcher(data);
- data->eventDispatcher.storeRelease(eventDispatcher);
- }
-
- eventDispatcher->startingUp();
+ data->ensureEventDispatcher();
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
@@ -449,6 +444,8 @@ void QThread::yieldCurrentThread()
#endif
}
+#endif // QT_NO_THREAD
+
void QThread::sleep(unsigned long secs)
{
::Sleep(secs * 1000);
@@ -464,6 +461,8 @@ void QThread::usleep(unsigned long usecs)
::Sleep((usecs / 1000) + 1);
}
+#ifndef QT_NO_THREAD
+
void QThread::start(Priority priority)
{
Q_D(QThread);
@@ -700,5 +699,6 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
}
}
-QT_END_NAMESPACE
#endif // QT_NO_THREAD
+
+QT_END_NAMESPACE
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index a0c6766833..e42efbdfca 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
+class QDeadlineTimer;
class QWaitConditionPrivate;
class QMutex;
class QReadWriteLock;
@@ -59,8 +60,11 @@ 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);
void wakeOne();
void wakeAll();
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index 6adee5412e..9706be1504 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -44,6 +44,8 @@
#include "qreadwritelock.h"
#include "qatomic.h"
#include "qstring.h"
+#include "qdeadlinetimer.h"
+#include "private/qdeadlinetimer_p.h"
#include "qelapsedtimer.h"
#include "private/qcore_unix_p.h"
@@ -93,23 +95,25 @@ void qt_initialize_pthread_cond(pthread_cond_t *cond, const char *where)
pthread_condattr_destroy(&condattr);
}
-void qt_abstime_for_timeout(timespec *ts, int timeout)
+void qt_abstime_for_timeout(timespec *ts, QDeadlineTimer deadline)
{
#ifdef Q_OS_MAC
// on Mac, qt_gettime() (on qelapsedtimer_mac.cpp) returns ticks related to the Mach absolute time
// that doesn't work with pthread
// Mac also doesn't have clock_gettime
struct timeval tv;
+ qint64 nsec = deadline.remainingTimeNSecs();
gettimeofday(&tv, 0);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
-#else
- *ts = qt_gettime();
-#endif
+ ts->tv_sec = tv.tv_sec + nsec / (1000 * 1000 * 1000);
+ ts->tv_nsec = tv.tv_usec * 1000 + nsec % (1000 * 1000 * 1000);
- ts->tv_sec += timeout / 1000;
- ts->tv_nsec += timeout % 1000 * Q_UINT64_C(1000) * 1000;
normalizedTimespec(*ts);
+#else
+ // depends on QDeadlineTimer's internals!!
+ Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2);
+ ts->tv_sec = deadline._q_data().first;
+ ts->tv_nsec = deadline._q_data().second;
+#endif
}
class QWaitConditionPrivate {
@@ -119,26 +123,27 @@ public:
int waiters;
int wakeups;
- int wait_relative(unsigned long time)
+ int wait_relative(QDeadlineTimer deadline)
{
timespec ti;
#ifdef Q_OS_ANDROID
- if (local_cond_timedwait_relative) {
- ti.tv_sec = time / 1000;
- ti.tv_nsec = time % 1000 * Q_UINT64_C(1000) * 1000;
+ if (!local_condattr_setclock && local_cond_timedwait_relative) {
+ qint64 nsec = deadline.remainingTimeNSecs();
+ ti.tv_sec = nsec / (1000 * 1000 * 1000);
+ ti.tv_nsec = nsec - ti.tv_sec * 1000 * 1000 * 1000;
return local_cond_timedwait_relative(&cond, &mutex, &ti);
}
#endif
- qt_abstime_for_timeout(&ti, time);
+ qt_abstime_for_timeout(&ti, deadline);
return pthread_cond_timedwait(&cond, &mutex, &ti);
}
- bool wait(unsigned long time)
+ bool wait(QDeadlineTimer deadline)
{
int code;
forever {
- if (time != ULONG_MAX) {
- code = wait_relative(time);
+ if (!deadline.isForever()) {
+ code = wait_relative(deadline);
} else {
code = pthread_cond_wait(&cond, &mutex);
}
@@ -201,6 +206,13 @@ void QWaitCondition::wakeAll()
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
+ if (quint64(time) > quint64(std::numeric_limits<qint64>::max()))
+ return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever));
+ return wait(mutex, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
if (! mutex)
return false;
if (mutex->isRecursive()) {
@@ -212,7 +224,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
++d->waiters;
mutex->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
mutex->lock();
@@ -221,6 +233,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
+ return wait(readWriteLock, QDeadlineTimer(time));
+}
+
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
if (!readWriteLock)
return false;
auto previousState = readWriteLock->stateForWaitCondition();
@@ -236,7 +253,7 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
readWriteLock->unlock();
- bool returnValue = d->wait(time);
+ bool returnValue = d->wait(deadline);
if (previousState == QReadWriteLock::LockedForWrite)
readWriteLock->lockForWrite();
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index e6610f18c8..61e4c2bcb1 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qwaitcondition.h"
+#include "qdeadlinetimer.h"
#include "qnamespace.h"
#include "qmutex.h"
#include "qreadwritelock.h"
@@ -184,6 +185,11 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline)
+{
+ return wait(mutex, deadline.remainingTime());
+}
+
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
if (!readWriteLock)
@@ -210,6 +216,11 @@ bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
return returnValue;
}
+bool QWaitCondition::wait(QReadWriteLock *readWriteLock, QDeadlineTimer deadline)
+{
+ return wait(readWriteLock, deadline.remainingTime());
+}
+
void QWaitCondition::wakeOne()
{
// wake up the first waiting thread in the queue