QWaylandDisplay: fix data race on m_quitting

WARNING: ThreadSanitizer: data race (pid=247514)
   Write of size 1 at 0x7214000026f5 by main thread (mutexes: write M0):
     #0 QtWaylandClient::EventThread::stop() (libQt6WaylandClient_tsan.so.6+0xbb696)

   Previous read of size 1 at 0x7214000026f5 by thread T3:
     #0 QtWaylandClient::EventThread::waitForReading() (libQt6WaylandClient_tsan.so.6+0xbbbf9)
     #1 QtWaylandClient::EventThread::run() (libQt6WaylandClient_tsan.so.6+0xbba27)

Pick-to: 6.9 6.8
Change-Id: I4a5dc95668619d337181e6c5055cc94bbc5fc7ae
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
David Faure 2025-03-09 13:04:39 +01:00
parent 9155b2ecb4
commit 7d77e1d9f8

View File

@ -106,13 +106,13 @@ public:
* not only the one issued from event thread's waitForReading(), which means functions * not only the one issued from event thread's waitForReading(), which means functions
* called from dispatch_pending() can safely spin an event loop. * called from dispatch_pending() can safely spin an event loop.
*/ */
if (m_quitting) if (m_quitting.loadRelaxed())
return; return;
for (;;) { for (;;) {
if (dispatchQueuePending() < 0) { if (dispatchQueuePending() < 0) {
Q_EMIT waylandError(); Q_EMIT waylandError();
m_quitting = true; m_quitting.storeRelaxed(true);
return; return;
} }
@ -139,11 +139,8 @@ public:
if (m_pipefd[1] != -1 && write(m_pipefd[1], "\0", 1) == -1) if (m_pipefd[1] != -1 && write(m_pipefd[1], "\0", 1) == -1)
qWarning("Failed to write to the pipe: %s.", strerror(errno)); qWarning("Failed to write to the pipe: %s.", strerror(errno));
{ m_quitting.storeRelaxed(true);
QMutexLocker l(&m_mutex);
m_quitting = true;
m_cond.wakeOne(); m_cond.wakeOne();
}
wait(); wait();
} }
@ -216,11 +213,11 @@ private:
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
// m_reading might be set from our emit or some other invocation of // m_reading might be set from our emit or some other invocation of
// readAndDispatchEvents(). // readAndDispatchEvents().
while (!m_reading.loadRelaxed() && !m_quitting) while (!m_reading.loadRelaxed() && !m_quitting.loadRelaxed())
m_cond.wait(&m_mutex); m_cond.wait(&m_mutex);
} }
return !m_quitting; return !m_quitting.loadRelaxed();
} }
int dispatchQueuePending() int dispatchQueuePending()
@ -255,7 +252,7 @@ private:
*/ */
QAtomicInteger<bool> m_reading; QAtomicInteger<bool> m_reading;
bool m_quitting; QAtomicInteger<bool> m_quitting;
QMutex m_mutex; QMutex m_mutex;
QWaitCondition m_cond; QWaitCondition m_cond;
}; };