summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qthread_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qthread_unix.cpp')
-rw-r--r--src/corelib/thread/qthread_unix.cpp61
1 files changed, 40 insertions, 21 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 777aa362b2..617a5ebf28 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -8,6 +8,7 @@
#include <private/qcoreapplication_p.h>
#include <private/qcore_unix_p.h>
+#include <private/qtools_p.h>
#if defined(Q_OS_DARWIN)
# include <private/qeventdispatcher_cf_p.h>
@@ -19,7 +20,9 @@
# endif
#endif
-#include <private/qeventdispatcher_unix_p.h>
+#if !defined(Q_OS_WASM)
+# include <private/qeventdispatcher_unix_p.h>
+#endif
#include "qthreadstorage.h"
@@ -70,6 +73,8 @@
QT_BEGIN_NAMESPACE
+using namespace QtMiscUtils;
+
#if QT_CONFIG(thread)
static_assert(sizeof(pthread_t) <= sizeof(Qt::HANDLE));
@@ -141,25 +146,25 @@ static void clear_thread_data()
}
template <typename T>
-static typename std::enable_if<QTypeInfo<T>::isIntegral, Qt::HANDLE>::type to_HANDLE(T id)
+static typename std::enable_if<std::is_integral_v<T>, Qt::HANDLE>::type to_HANDLE(T id)
{
return reinterpret_cast<Qt::HANDLE>(static_cast<intptr_t>(id));
}
template <typename T>
-static typename std::enable_if<QTypeInfo<T>::isIntegral, T>::type from_HANDLE(Qt::HANDLE id)
+static typename std::enable_if<std::is_integral_v<T>, T>::type from_HANDLE(Qt::HANDLE id)
{
return static_cast<T>(reinterpret_cast<intptr_t>(id));
}
template <typename T>
-static typename std::enable_if<QTypeInfo<T>::isPointer, Qt::HANDLE>::type to_HANDLE(T id)
+static typename std::enable_if<std::is_pointer_v<T>, Qt::HANDLE>::type to_HANDLE(T id)
{
return id;
}
template <typename T>
-static typename std::enable_if<QTypeInfo<T>::isPointer, T>::type from_HANDLE(Qt::HANDLE id)
+static typename std::enable_if<std::is_pointer_v<T>, T>::type from_HANDLE(Qt::HANDLE id)
{
return static_cast<T>(id);
}
@@ -186,8 +191,10 @@ QThreadData *QThreadData::current(bool createIfNecessary)
data->deref();
data->isAdopted = true;
data->threadId.storeRelaxed(to_HANDLE(pthread_self()));
- if (!QCoreApplicationPrivate::theMainThread.loadAcquire())
+ if (!QCoreApplicationPrivate::theMainThreadId.loadAcquire()) {
QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed());
+ QCoreApplicationPrivate::theMainThreadId.storeRelaxed(data->threadId.loadRelaxed());
+ }
}
return data;
}
@@ -234,12 +241,12 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat
#if QT_CONFIG(thread)
-#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
+#if (defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) || defined(Q_OS_QNX))
static void setCurrentThreadName(const char *name)
{
# if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
-# elif defined(Q_OS_MAC)
+# elif defined(Q_OS_DARWIN)
pthread_setname_np(name);
# elif defined(Q_OS_QNX)
pthread_setname_np(pthread_self(), name);
@@ -272,7 +279,7 @@ void terminate_on_exception(T &&t)
void *QThreadPrivate::start(void *arg)
{
-#if !defined(Q_OS_ANDROID)
+#ifdef PTHREAD_CANCEL_DISABLE
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
#endif
pthread_cleanup_push(QThreadPrivate::finish, arg);
@@ -301,7 +308,7 @@ void *QThreadPrivate::start(void *arg)
data->ensureEventDispatcher();
data->eventDispatcher.loadRelaxed()->startingUp();
-#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
+#if (defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) || defined(Q_OS_QNX))
{
// Sets the name of the current thread. We can only do this
// when the thread is starting, as we don't have a cross
@@ -314,7 +321,7 @@ void *QThreadPrivate::start(void *arg)
#endif
emit thr->started(QThread::QPrivateSignal());
-#if !defined(Q_OS_ANDROID)
+#ifdef PTHREAD_CANCEL_DISABLE
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, nullptr);
pthread_testcancel();
#endif
@@ -342,6 +349,7 @@ void QThreadPrivate::finish(void *arg)
void *data = &d->data->tls;
locker.unlock();
emit thr->finished(QThread::QPrivateSignal());
+ qCDebug(lcDeleteLater) << "Sending deferred delete events as part of finishing thread" << thr;
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
QThreadStorageData::finish((void **)data);
locker.relock();
@@ -357,7 +365,7 @@ void QThreadPrivate::finish(void *arg)
d->running = false;
d->finished = true;
- d->interruptionRequested = false;
+ d->interruptionRequested.store(false, std::memory_order_relaxed);
d->isInFinish = false;
d->data->threadId.storeRelaxed(nullptr);
@@ -488,27 +496,38 @@ void QThread::yieldCurrentThread()
#endif // QT_CONFIG(thread)
-static timespec makeTimespec(time_t secs, long nsecs)
+static void qt_nanosleep(timespec amount)
{
- struct timespec ts;
- ts.tv_sec = secs;
- ts.tv_nsec = nsecs;
- return ts;
+ // We'd like to use clock_nanosleep.
+ //
+ // But clock_nanosleep is from POSIX.1-2001 and both are *not*
+ // affected by clock changes when using relative sleeps, even for
+ // CLOCK_REALTIME.
+ //
+ // nanosleep is POSIX.1-1993
+
+ int r;
+ QT_EINTR_LOOP(r, nanosleep(&amount, &amount));
}
void QThread::sleep(unsigned long secs)
{
- qt_nanosleep(makeTimespec(secs, 0));
+ sleep(std::chrono::seconds{secs});
}
void QThread::msleep(unsigned long msecs)
{
- qt_nanosleep(makeTimespec(msecs / 1000, msecs % 1000 * 1000 * 1000));
+ sleep(std::chrono::milliseconds{msecs});
}
void QThread::usleep(unsigned long usecs)
{
- qt_nanosleep(makeTimespec(usecs / 1000 / 1000, usecs % (1000*1000) * 1000));
+ sleep(std::chrono::microseconds{usecs});
+}
+
+void QThread::sleep(std::chrono::nanoseconds nsec)
+{
+ qt_nanosleep(durationToTimespec(nsec));
}
#if QT_CONFIG(thread)
@@ -623,7 +642,7 @@ void QThread::start(Priority priority)
d->finished = false;
d->returnCode = 0;
d->exited = false;
- d->interruptionRequested = false;
+ d->interruptionRequested.store(false, std::memory_order_relaxed);
pthread_attr_t attr;
pthread_attr_init(&attr);