diff options
author | Marc Mutz <marc.mutz@qt.io> | 2021-12-22 15:01:27 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2021-12-30 17:45:07 +0000 |
commit | f0ffe351492a7d8e9fac8a8e060b906b4b8a733a (patch) | |
tree | 994618ea31c1c0584bf1011e95095ea908416ff3 /src | |
parent | c760fba40e9f7c9c0883baa07a8561380668700c (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')
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 63 |
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 + }); } |