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>
This commit is contained in:
parent
c760fba40e
commit
f0ffe35149
@ -284,6 +284,29 @@ static void setCurrentThreadName(const char *name)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
void *QThreadPrivate::start(void *arg)
|
||||||
{
|
{
|
||||||
#if !defined(Q_OS_ANDROID)
|
#if !defined(Q_OS_ANDROID)
|
||||||
@ -291,10 +314,7 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
#endif
|
#endif
|
||||||
pthread_cleanup_push(QThreadPrivate::finish, arg);
|
pthread_cleanup_push(QThreadPrivate::finish, arg);
|
||||||
|
|
||||||
#ifndef QT_NO_EXCEPTIONS
|
terminate_on_exception([&] {
|
||||||
try
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
QThread *thr = reinterpret_cast<QThread *>(arg);
|
||||||
QThreadData *data = QThreadData::get2(thr);
|
QThreadData *data = QThreadData::get2(thr);
|
||||||
|
|
||||||
@ -336,20 +356,7 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
pthread_testcancel();
|
pthread_testcancel();
|
||||||
#endif
|
#endif
|
||||||
thr->run();
|
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
|
// 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
|
// 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)
|
void QThreadPrivate::finish(void *arg)
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_EXCEPTIONS
|
terminate_on_exception([&] {
|
||||||
try
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
QThread *thr = reinterpret_cast<QThread *>(arg);
|
||||||
QThreadPrivate *d = thr->d_func();
|
QThreadPrivate *d = thr->d_func();
|
||||||
|
|
||||||
@ -396,20 +400,7 @@ void QThreadPrivate::finish(void *arg)
|
|||||||
d->data->threadId.storeRelaxed(nullptr);
|
d->data->threadId.storeRelaxed(nullptr);
|
||||||
|
|
||||||
d->thread_done.wakeAll();
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user