diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index f7328641aed..3c876cdcf15 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -195,6 +195,9 @@ public: State threadState = NotStarted; bool exited = false; std::atomic interruptionRequested = false; +#ifdef Q_OS_UNIX + bool terminated = false; // when (the first) terminate has been called +#endif int returnCode = -1; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 3f2b902eb0a..4158e8aecbc 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -644,6 +644,7 @@ void QThread::start(Priority priority) d->returnCode = 0; d->exited = false; d->interruptionRequested.store(false, std::memory_order_relaxed); + d->terminated = false; pthread_attr_t attr; pthread_attr_init(&attr); @@ -753,8 +754,14 @@ void QThread::terminate() if (!d->data->threadId.loadRelaxed()) return; + if (d->terminated) // don't try again, avoids killing the wrong thread on threadId reuse (ABA) + return; + + d->terminated = true; + int code = pthread_cancel(from_HANDLE(d->data->threadId.loadRelaxed())); if (code) { + d->terminated = false; // allow to try again qErrnoWarning(code, "QThread::start: Thread termination error"); } #endif