diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2016-10-04 16:45:15 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2016-10-06 05:31:02 +0000 |
commit | 43081c1b7a8cc29d6dffc87dd0ef72faecf7233e (patch) | |
tree | f6edf79453cd2e82b1d53a6eb772c99b48b2784b | |
parent | 2e44df5f5ca13cac61886d33ce3f4a4232f1ad80 (diff) | |
download | qtwayland-43081c1b7a8cc29d6dffc87dd0ef72faecf7233e.tar.gz |
Fix race condition on mFrameCallback
Don't try to destroy the callback from two different threads. This
caused a crash with brcm-egl.
Change-Id: Idcb18fca9ed7f84902b88212c0cebd67932a59d3
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
-rw-r--r-- | src/client/qwaylandwindow.cpp | 14 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 3 |
2 files changed, 8 insertions, 9 deletions
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index e8f3ceb4..59c446bb 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -83,7 +83,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mMousePressedInContentArea(Qt::NoButton) , m_cursor(Qt::ArrowCursor) , mWaitingForFrameSync(false) - , mFrameCallback(0) + , mFrameCallback(nullptr) , mRequestResizeSent(false) , mCanResize(true) , mResizeDirty(false) @@ -453,14 +453,12 @@ void QWaylandWindow::requestResize() void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = 0; - } + mFrameCallback = nullptr; if (buffer) { - mFrameCallback = frame(); - wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); + auto callback = frame(); + wl_callback_add_listener(callback, &QWaylandWindow::callbackListener, this); + mFrameCallback = callback; mWaitingForFrameSync = true; attach(buffer->buffer(), x, y); @@ -491,7 +489,7 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin self->mWaitingForFrameSync = false; wl_callback_destroy(callback); - self->mFrameCallback = 0; + self->mFrameCallback.testAndSetRelaxed(callback, nullptr); if (self->mUpdateRequested) { QWindowPrivate *w = QWindowPrivate::get(self->window()); self->mUpdateRequested = false; diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 03c4a1e4..e0c42ace 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -53,6 +53,7 @@ #include <QtCore/QWaitCondition> #include <QtCore/QMutex> +#include <QtCore/QAtomicPointer> #include <QtGui/QIcon> #include <QtCore/QVariant> @@ -220,7 +221,7 @@ protected: WId mWindowId; bool mWaitingForFrameSync; - struct wl_callback *mFrameCallback; + QAtomicPointer<struct wl_callback> mFrameCallback; QWaitCondition mFrameSyncWait; QMutex mResizeLock; |