diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 4918fd7b852..e429362514d 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -188,6 +188,9 @@ public: bool finished; bool isInFinish; //when in QThreadPrivate::finish std::atomic interruptionRequested = false; +#ifdef Q_OS_UNIX + bool terminated = false; // when (the first) terminate has been called +#endif bool exited; int returnCode; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index de18bcb0969..a56a764eed5 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -647,6 +647,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); @@ -758,8 +759,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