diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qfuturewatcher.cpp | 12 | ||||
-rw-r--r-- | src/corelib/thread/qorderedmutexlocker_p.h | 6 | ||||
-rw-r--r-- | src/corelib/thread/qthread_p.h | 9 | ||||
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 74 | ||||
-rw-r--r-- | src/corelib/thread/qthread_win.cpp | 12 |
5 files changed, 60 insertions, 53 deletions
diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp index 06bc4740f9..ecde665e1f 100644 --- a/src/corelib/thread/qfuturewatcher.cpp +++ b/src/corelib/thread/qfuturewatcher.cpp @@ -511,9 +511,15 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event) Starts watching the given \a future. - One of the signals might be emitted for the current state of the - \a future. For example, if the future is already stopped, the - finished signal will be emitted. + If \a future has already started, the watcher will initially emit signals + that bring their listeners up to date about the future's state. The + following signals will, if applicable, be emitted in the given order: + started(), progressRangeChanged(), progressValueChanged(), + progressTextChanged(), resultsReadyAt(), resultReadyAt(), paused(), + canceled(), and finished(). Of these, resultsReadyAt() and + resultReadyAt() may be emitted several times to cover all available + results. progressValueChanged() and progressTextChanged() will only be + emitted once for the latest available progress value and text. To avoid a race condition, it is important to call this function \e after doing the connections. diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h index 9a9aaefa02..309413173e 100644 --- a/src/corelib/thread/qorderedmutexlocker_p.h +++ b/src/corelib/thread/qorderedmutexlocker_p.h @@ -91,9 +91,9 @@ public: } QOrderedMutexLocker(QOrderedMutexLocker &&other) noexcept - : mtx1(std::exchange(other.mtx1, nullptr)) - , mtx2(std::exchange(other.mtx2, nullptr)) - , locked(std::exchange(other.locked, false)) + : mtx1(qExchange(other.mtx1, nullptr)) + , mtx2(qExchange(other.mtx2, nullptr)) + , locked(qExchange(other.locked, false)) {} ~QOrderedMutexLocker() diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index b2d1628e6e..f32f6f0460 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -174,7 +174,7 @@ public: int returnCode; uint stackSize; - QThread::Priority priority; + std::underlying_type<QThread::Priority>::type priority; static QThread *threadForId(int id); @@ -213,6 +213,13 @@ public: QCoreApplication::instance()->postEvent(q_ptr, new QEvent(QEvent::Quit)); } } + +#ifndef Q_OS_INTEGRITY +private: + // Used in QThread(Private)::start to avoid racy access to QObject::objectName, + // unset afterwards. On INTEGRITY we set the thread name before starting it. + QString objectName; +#endif }; #else // QT_CONFIG(thread) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 56a8e0a038..f6499b38d0 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -278,6 +278,29 @@ static void setCurrentThreadName(const char *name) } #endif +namespace { +template <typename T> +void terminate_on_exception(T &&t) +{ +#ifndef QT_NO_EXCEPTIONS + try { +#endif + std::forward<T>(t)(); +#ifndef QT_NO_EXCEPTIONS +#ifdef __GLIBCXX__ + // POSIX thread cancellation under glibc is implemented by throwing an exception + // of this type. Do what libstdc++ is doing and handle it specially in order not to + // abort the application if user's code calls a cancellation function. + } catch (abi::__forced_unwind &) { + throw; +#endif // __GLIBCXX__ + } catch (...) { + qTerminate(); + } +#endif // QT_NO_EXCEPTIONS +} +} // unnamed namespace + void *QThreadPrivate::start(void *arg) { #if !defined(Q_OS_ANDROID) @@ -285,10 +308,7 @@ void *QThreadPrivate::start(void *arg) #endif pthread_cleanup_push(QThreadPrivate::finish, arg); -#ifndef QT_NO_EXCEPTIONS - try -#endif - { + terminate_on_exception([&] { QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); @@ -296,7 +316,7 @@ void *QThreadPrivate::start(void *arg) QMutexLocker locker(&thr->d_func()->mutex); // do we need to reset the thread priority? - if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) { + if (thr->d_func()->priority & ThreadPriorityResetFlag) { thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); } @@ -316,10 +336,10 @@ void *QThreadPrivate::start(void *arg) // Sets the name of the current thread. We can only do this // when the thread is starting, as we don't have a cross // platform way of setting the name of an arbitrary thread. - if (Q_LIKELY(thr->objectName().isEmpty())) + if (Q_LIKELY(thr->d_func()->objectName.isEmpty())) setCurrentThreadName(thr->metaObject()->className()); else - setCurrentThreadName(thr->objectName().toLocal8Bit()); + setCurrentThreadName(std::exchange(thr->d_func()->objectName, {}).toLocal8Bit()); } #endif @@ -329,20 +349,7 @@ void *QThreadPrivate::start(void *arg) pthread_testcancel(); #endif thr->run(); - } -#ifndef QT_NO_EXCEPTIONS -#ifdef __GLIBCXX__ - // POSIX thread cancellation under glibc is implemented by throwing an exception - // of this type. Do what libstdc++ is doing and handle it specially in order not to - // abort the application if user's code calls a cancellation function. - catch (const abi::__forced_unwind &) { - throw; - } -#endif // __GLIBCXX__ - catch (...) { - qTerminate(); - } -#endif // QT_NO_EXCEPTIONS + }); // This pop runs finish() below. It's outside the try/catch (and has its // own try/catch) to prevent finish() to be run in case an exception is @@ -354,10 +361,7 @@ void *QThreadPrivate::start(void *arg) void QThreadPrivate::finish(void *arg) { -#ifndef QT_NO_EXCEPTIONS - try -#endif - { + terminate_on_exception([&] { QThread *thr = reinterpret_cast<QThread *>(arg); QThreadPrivate *d = thr->d_func(); @@ -389,20 +393,7 @@ void QThreadPrivate::finish(void *arg) d->data->threadId.storeRelaxed(nullptr); d->thread_done.wakeAll(); - } -#ifndef QT_NO_EXCEPTIONS -#ifdef __GLIBCXX__ - // POSIX thread cancellation under glibc is implemented by throwing an exception - // of this type. Do what libstdc++ is doing and handle it specially in order not to - // abort the application if user's code calls a cancellation function. - catch (const abi::__forced_unwind &) { - throw; - } -#endif // __GLIBCXX__ - catch (...) { - qTerminate(); - } -#endif // QT_NO_EXCEPTIONS + }); } @@ -671,7 +662,7 @@ void QThread::start(Priority priority) // could not set scheduling hints, fallback to inheriting them // we'll try again from inside the thread pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); - d->priority = Priority(priority | ThreadPriorityResetFlag); + d->priority = std::underlying_type<Priority>::type(priority) | ThreadPriorityResetFlag; } break; } @@ -702,7 +693,10 @@ void QThread::start(Priority priority) pthread_attr_setthreadname(&attr, metaObject()->className()); else pthread_attr_setthreadname(&attr, objectName().toLocal8Bit()); +#else + d->objectName = objectName(); #endif + pthread_t threadId; int code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); if (code == EPERM) { diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index bc70e3178a..4e76972498 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -394,10 +394,9 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi #if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT) // sets the name of the current thread. - QByteArray objectName = thr->objectName().toLocal8Bit(); - qt_set_thread_name(HANDLE(-1), - objectName.isEmpty() ? - thr->metaObject()->className() : objectName.constData()); + qt_set_thread_name(HANDLE(-1), thr->d_func()->objectName.isEmpty() + ? thr->metaObject()->className() + : std::exchange(thr->d_func()->objectName, {}).toLocal8Bit().constData()); #endif emit thr->started(QThread::QPrivateSignal()); @@ -503,6 +502,7 @@ void QThread::start(Priority priority) if (d->running) return; + d->objectName = objectName(); d->running = true; d->finished = false; d->exited = false; @@ -548,7 +548,7 @@ void QThread::start(Priority priority) int prio; d->priority = priority; - switch (d->priority) { + switch (priority) { case IdlePriority: prio = THREAD_PRIORITY_IDLE; break; @@ -686,7 +686,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int prio; priority = threadPriority; - switch (priority) { + switch (threadPriority) { case QThread::IdlePriority: prio = THREAD_PRIORITY_IDLE; break; |