summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qthread_unix.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2021-12-22 15:01:27 +0100
committerMarc Mutz <marc.mutz@qt.io>2021-12-30 17:45:07 +0000
commitf0ffe351492a7d8e9fac8a8e060b906b4b8a733a (patch)
tree994618ea31c1c0584bf1011e95095ea908416ff3 /src/corelib/thread/qthread_unix.cpp
parentc760fba40e9f7c9c0883baa07a8561380668700c (diff)
QThread/Unix: extract duplicate code
Extract function terminate_on_exception() that de-duplicates the #ifdef'ery around the try/catch and the handling of the pthread cancellation pseudo-exception. Apart from de-duplicating complex code, it will also help suppressing a ubsan false positive, which is why we're picking it all the way to 5.15. Pick-to: 6.3 6.2 5.15 Change-Id: I99ad2c0618b8dc30801931df09400c6611d9f9e4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread/qthread_unix.cpp')
-rw-r--r--src/corelib/thread/qthread_unix.cpp63
1 files changed, 27 insertions, 36 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 79abfe7e50..85fb5b1034 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -284,6 +284,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)
@@ -291,10 +314,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);
@@ -336,20 +356,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
@@ -361,10 +368,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();
@@ -396,20 +400,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
+ });
}