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.cpp39
1 files changed, 18 insertions, 21 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 4b165eef9c..13b061d7c7 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -43,11 +43,8 @@
# include <sys/sysctl.h>
#endif
#ifdef Q_OS_VXWORKS
-# if (_WRS_VXWORKS_MAJOR > 6) || ((_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR >= 6))
-# include <vxCpuLib.h>
-# include <cpuset.h>
-# define QT_VXWORKS_HAS_CPUSET
-# endif
+# include <vxCpuLib.h>
+# include <cpuset.h>
#endif
#ifdef Q_OS_HPUX
@@ -191,8 +188,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;
}
@@ -280,8 +279,16 @@ void *QThreadPrivate::start(void *arg)
#ifdef PTHREAD_CANCEL_DISABLE
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, nullptr);
#endif
- pthread_cleanup_push(QThreadPrivate::finish, arg);
-
+#if !defined(Q_OS_QNX) && !defined(Q_OS_VXWORKS)
+ // On QNX, calling finish() from a thread_local destructor causes the C
+ // library to hang.
+ // On VxWorks, its pthread implementation fails on call to `pthead_setspecific` which is made
+ // by first QObject constructor during `finish()`. This causes call to QThread::current, since
+ // QObject doesn't have parent, and since the pthread is already removed, it tries to set
+ // QThreadData for current pthread key, which crashes.
+ static thread_local
+#endif
+ auto cleanup = qScopeGuard([=] { finish(arg); });
terminate_on_exception([&] {
QThread *thr = reinterpret_cast<QThread *>(arg);
QThreadData *data = QThreadData::get2(thr);
@@ -326,11 +333,7 @@ void *QThreadPrivate::start(void *arg)
thr->run();
});
- // 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
- // thrown.
- pthread_cleanup_pop(1);
-
+ // The qScopeGuard above call runs finish() below.
return nullptr;
}
@@ -363,7 +366,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);
@@ -460,8 +463,6 @@ int QThread::idealThreadCount() noexcept
// as of aug 2008 Integrity only supports one single core CPU
cores = 1;
#elif defined(Q_OS_VXWORKS)
- // VxWorks
-# if defined(QT_VXWORKS_HAS_CPUSET)
cpuset_t cpus = vxCpuEnabledGet();
cores = 0;
@@ -472,10 +473,6 @@ int QThread::idealThreadCount() noexcept
cores++;
}
}
-# else
- // as of aug 2008 VxWorks < 6.6 only supports one single core CPU
- cores = 1;
-# endif
#elif defined(Q_OS_WASM)
cores = QThreadPrivate::idealThreadCount;
#else
@@ -640,7 +637,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);