Fix race condition on mWaitingForUpdateDelivery

Change-Id: I0e91bda73722468b9339fc434fe04420b5e7d3da
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Paul Olav Tvete 2022-03-15 16:53:04 +01:00
parent eddb08768f
commit b41a7e47ee
2 changed files with 3 additions and 5 deletions

View File

@ -716,18 +716,17 @@ void QWaylandWindow::handleFrameCallback()
mFrameCallbackElapsedTimer.invalidate();
// The rest can wait until we can run it on the correct thread
if (!mWaitingForUpdateDelivery) {
if (mWaitingForUpdateDelivery.testAndSetAcquire(false, true)) {
// Queued connection, to make sure we don't call handleUpdate() from inside waitForFrameSync()
// in the single-threaded case.
mWaitingForUpdateDelivery = true;
QMetaObject::invokeMethod(this, &QWaylandWindow::doHandleFrameCallback, Qt::QueuedConnection);
}
mFrameSyncWait.notify_all();
}
void QWaylandWindow::doHandleFrameCallback()
{
mWaitingForUpdateDelivery.storeRelease(false);
bool wasExposed = isExposed();
mFrameCallbackTimedOut = false;
if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed?
@ -735,7 +734,6 @@ void QWaylandWindow::doHandleFrameCallback()
if (wasExposed && hasPendingUpdateRequest())
deliverUpdateRequest();
mWaitingForUpdateDelivery = false;
}
bool QWaylandWindow::waitForFrameSync(int timeout)

View File

@ -283,7 +283,7 @@ protected:
WId mWindowId;
bool mWaitingForFrameCallback = false;
bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out
bool mWaitingForUpdateDelivery = false;
QAtomicInt mWaitingForUpdateDelivery = false;
int mFrameCallbackCheckIntervalTimerId = -1;
QElapsedTimer mFrameCallbackElapsedTimer;
struct ::wl_callback *mFrameCallback = nullptr;