QThread: make finish() and cleanup() non-static members
Looks cleaner. Change-Id: I77148a15c316ea0eaf63fffd9358d952c5b9e1d0 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit f94c9b0f3a060fa98c270d5ccab3055e77ebc35f) Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
334a3922c0
commit
90c436dd1e
@ -202,13 +202,13 @@ public:
|
|||||||
QWaitCondition thread_done;
|
QWaitCondition thread_done;
|
||||||
|
|
||||||
static void *start(void *arg);
|
static void *start(void *arg);
|
||||||
static void finish(void *); // happens early (before thread-local dtors)
|
void finish(); // happens early (before thread-local dtors)
|
||||||
static void cleanup(void *); // happens late (as a thread-local dtor, if possible)
|
void cleanup(); // happens late (as a thread-local dtor, if possible)
|
||||||
#endif // Q_OS_UNIX
|
#endif // Q_OS_UNIX
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
static unsigned int __stdcall start(void *) noexcept;
|
static unsigned int __stdcall start(void *) noexcept;
|
||||||
static void finish(void *, bool lockAnyway = true) noexcept;
|
void finish(bool lockAnyway = true) noexcept;
|
||||||
|
|
||||||
Qt::HANDLE handle;
|
Qt::HANDLE handle;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
@ -112,15 +112,15 @@ static void destroy_current_thread_data(void *p)
|
|||||||
// this is very likely the last reference. These pointers cannot be
|
// this is very likely the last reference. These pointers cannot be
|
||||||
// null and there is no race.
|
// null and there is no race.
|
||||||
QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
||||||
thread_p->finish(thread);
|
thread_p->finish();
|
||||||
if constexpr (!QT_CONFIG(broken_threadlocal_dtors))
|
if constexpr (!QT_CONFIG(broken_threadlocal_dtors))
|
||||||
thread_p->cleanup(thread);
|
thread_p->cleanup();
|
||||||
} else if constexpr (!QT_CONFIG(broken_threadlocal_dtors)) {
|
} else if constexpr (!QT_CONFIG(broken_threadlocal_dtors)) {
|
||||||
// We may be racing the QThread destructor in another thread. With
|
// We may be racing the QThread destructor in another thread. With
|
||||||
// two-phase clean-up enabled, there's also no race because it will
|
// two-phase clean-up enabled, there's also no race because it will
|
||||||
// stop in a call to QThread::wait() until we call cleanup().
|
// stop in a call to QThread::wait() until we call cleanup().
|
||||||
QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
||||||
thread_p->cleanup(thread);
|
thread_p->cleanup();
|
||||||
} else {
|
} else {
|
||||||
// We may be racing the QThread destructor in another thread and it may
|
// We may be racing the QThread destructor in another thread and it may
|
||||||
// have begun destruction; we must not dereference the QThread pointer.
|
// have begun destruction; we must not dereference the QThread pointer.
|
||||||
@ -314,7 +314,7 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
// this ensures the thread-local is created as early as possible
|
// this ensures the thread-local is created as early as possible
|
||||||
set_thread_data(data);
|
set_thread_data(data);
|
||||||
|
|
||||||
pthread_cleanup_push(QThreadPrivate::finish, arg);
|
pthread_cleanup_push([](void *arg) { static_cast<QThread *>(arg)->d_func()->finish(); }, arg);
|
||||||
terminate_on_exception([&] {
|
terminate_on_exception([&] {
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&thr->d_func()->mutex);
|
QMutexLocker locker(&thr->d_func()->mutex);
|
||||||
@ -361,11 +361,11 @@ void *QThreadPrivate::start(void *arg)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QThreadPrivate::finish(void *arg)
|
void QThreadPrivate::finish()
|
||||||
{
|
{
|
||||||
terminate_on_exception([&] {
|
terminate_on_exception([&] {
|
||||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
QThreadPrivate *d = this;
|
||||||
QThreadPrivate *d = thr->d_func();
|
QThread *thr = q_func();
|
||||||
|
|
||||||
// Disable cancellation; we're already in the finishing touches of this
|
// Disable cancellation; we're already in the finishing touches of this
|
||||||
// thread, and we don't want cleanup to be disturbed by
|
// thread, and we don't want cleanup to be disturbed by
|
||||||
@ -388,14 +388,13 @@ void QThreadPrivate::finish(void *arg)
|
|||||||
});
|
});
|
||||||
|
|
||||||
if constexpr (QT_CONFIG(broken_threadlocal_dtors))
|
if constexpr (QT_CONFIG(broken_threadlocal_dtors))
|
||||||
cleanup(arg);
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QThreadPrivate::cleanup(void *arg)
|
void QThreadPrivate::cleanup()
|
||||||
{
|
{
|
||||||
terminate_on_exception([&] {
|
terminate_on_exception([&] {
|
||||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
QThreadPrivate *d = this;
|
||||||
QThreadPrivate *d = thr->d_func();
|
|
||||||
|
|
||||||
// Disable cancellation again: we did it above, but some user code
|
// Disable cancellation again: we did it above, but some user code
|
||||||
// running between finish() and cleanup() may have turned them back on.
|
// running between finish() and cleanup() may have turned them back on.
|
||||||
|
@ -209,7 +209,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
|
|||||||
auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
||||||
Q_UNUSED(thread_p);
|
Q_UNUSED(thread_p);
|
||||||
Q_ASSERT(!thread_p->finished);
|
Q_ASSERT(!thread_p->finished);
|
||||||
QThreadPrivate::finish(thread);
|
thread_p->finish();
|
||||||
}
|
}
|
||||||
data->deref();
|
data->deref();
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
|||||||
QThread::setTerminationEnabled(true);
|
QThread::setTerminationEnabled(true);
|
||||||
thr->run();
|
thr->run();
|
||||||
|
|
||||||
finish(arg);
|
thr->d_func()->finish();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,10 +284,10 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
|||||||
|
|
||||||
In those cases, \a arg will not be the current thread.
|
In those cases, \a arg will not be the current thread.
|
||||||
*/
|
*/
|
||||||
void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
|
void QThreadPrivate::finish(bool lockAnyway) noexcept
|
||||||
{
|
{
|
||||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
QThreadPrivate *d = this;
|
||||||
QThreadPrivate *d = thr->d_func();
|
QThread *thr = q_func();
|
||||||
|
|
||||||
QMutexLocker locker(lockAnyway ? &d->mutex : nullptr);
|
QMutexLocker locker(lockAnyway ? &d->mutex : nullptr);
|
||||||
d->isInFinish = true;
|
d->isInFinish = true;
|
||||||
@ -481,7 +481,7 @@ void QThread::terminate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
TerminateThread(d->handle, 0);
|
TerminateThread(d->handle, 0);
|
||||||
QThreadPrivate::finish(this, false);
|
d->finish(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QThread::wait(QDeadlineTimer deadline)
|
bool QThread::wait(QDeadlineTimer deadline)
|
||||||
@ -519,7 +519,7 @@ bool QThread::wait(QDeadlineTimer deadline)
|
|||||||
if (ret && !d->finished) {
|
if (ret && !d->finished) {
|
||||||
// thread was terminated by someone else
|
// thread was terminated by someone else
|
||||||
|
|
||||||
QThreadPrivate::finish(this, false);
|
d->finish(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->finished && !d->waiters) {
|
if (d->finished && !d->waiters) {
|
||||||
@ -539,7 +539,7 @@ void QThread::setTerminationEnabled(bool enabled)
|
|||||||
QMutexLocker locker(&d->mutex);
|
QMutexLocker locker(&d->mutex);
|
||||||
d->terminationEnabled = enabled;
|
d->terminationEnabled = enabled;
|
||||||
if (enabled && d->terminatePending) {
|
if (enabled && d->terminatePending) {
|
||||||
QThreadPrivate::finish(thr, false);
|
d->finish(false);
|
||||||
locker.unlock(); // don't leave the mutex locked!
|
locker.unlock(); // don't leave the mutex locked!
|
||||||
_endthreadex(0);
|
_endthreadex(0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user