summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGiulio Camuffo <giulio.camuffo@jollamobile.com>2015-06-17 14:48:44 +0300
committerGiulio Camuffo <giulio.camuffo@jollamobile.com>2015-07-06 08:00:02 +0000
commit8cc88f4854b72bb270e4b701d15ada7bdbb74ff4 (patch)
treefe7c3ed88fc1d1c469a6e61e104bd12c952b7ab4
parentcc694272c201e57e8bffdb770059e51ac998c5f9 (diff)
Fix possible race condition leading to a dead lock
It is a bit dangerous to call wl_display_dispatch() in the event thread, since it may race with the dispatch called e.g. in QWaylandDisplay's blockingReadEvents() and lead to a dead lock. Instead, use wl_display_prepare_read() and wl_display_read_events() in the event thread, which doesn't block, and only dispatch in QWaylandDisplay. As a result we don't need the additional wayland queue anymore, so remove it. Change-Id: I9fbbe5d2f38d06773beb7847df1a0212cca92c37 Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
-rw-r--r--examples/wayland/server-buffer/client/main.cpp1
-rw-r--r--src/client/qwaylanddisplay.cpp14
-rw-r--r--src/client/qwaylanddisplay_p.h2
-rw-r--r--src/client/qwaylandeventthread.cpp8
-rw-r--r--src/client/qwaylandnativeinterface.cpp2
5 files changed, 6 insertions, 21 deletions
diff --git a/examples/wayland/server-buffer/client/main.cpp b/examples/wayland/server-buffer/client/main.cpp
index 3f7a94d03..1a2c447a7 100644
--- a/examples/wayland/server-buffer/client/main.cpp
+++ b/examples/wayland/server-buffer/client/main.cpp
@@ -95,7 +95,6 @@ public:
QtWaylandClient::QWaylandDisplay *wayland_display = wayland_integration->display();
struct ::wl_registry *registry = wl_display_get_registry(wayland_display->wl_display());
- wl_proxy_set_queue(reinterpret_cast<struct wl_proxy *>(registry), wayland_display->wl_event_queue());
QtWayland::wl_registry::init(registry);
}
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index eb431cf0d..f197b3788 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -147,12 +147,7 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
mEventThreadObject->displayConnect();
mDisplay = mEventThreadObject->display(); //blocks until display is available
- //Create a new even queue for the QtGui thread
- mEventQueue = wl_display_create_queue(mDisplay);
-
struct ::wl_registry *registry = wl_display_get_registry(mDisplay);
- wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue);
-
init(registry);
connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests()));
@@ -180,7 +175,7 @@ QWaylandDisplay::~QWaylandDisplay(void)
void QWaylandDisplay::flushRequests()
{
- if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) {
+ if (wl_display_dispatch_pending(mDisplay) < 0) {
mEventThreadObject->checkError();
exitWithError();
}
@@ -191,7 +186,7 @@ void QWaylandDisplay::flushRequests()
void QWaylandDisplay::blockingReadEvents()
{
- if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) {
+ if (wl_display_dispatch(mDisplay) < 0) {
mEventThreadObject->checkError();
exitWithError();
}
@@ -345,17 +340,16 @@ void QWaylandDisplay::forceRoundTrip()
int ret = 0;
bool done = false;
wl_callback *callback = wl_display_sync(mDisplay);
- wl_proxy_set_queue((struct wl_proxy *)callback, mEventQueue);
wl_callback_add_listener(callback, &sync_listener, &done);
flushRequests();
if (QThread::currentThread()->eventDispatcher()) {
while (!done && ret >= 0) {
QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::WaitForMoreEvents);
- ret = wl_display_dispatch_queue_pending(mDisplay, mEventQueue);
+ ret = wl_display_dispatch_pending(mDisplay);
}
} else {
while (!done && ret >= 0)
- ret = wl_display_dispatch_queue(mDisplay, mEventQueue);
+ ret = wl_display_dispatch(mDisplay);
}
if (ret == -1 && !done)
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 7ba431d7c..ee129a50e 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -108,7 +108,6 @@ public:
void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image);
struct wl_display *wl_display() const { return mDisplay; }
- struct wl_event_queue *wl_event_queue() const { return mEventQueue; }
struct ::wl_registry *wl_registry() { return object(); }
const struct wl_compositor *wl_compositor() const { return mCompositor.object(); }
@@ -175,7 +174,6 @@ private:
};
struct wl_display *mDisplay;
- struct wl_event_queue *mEventQueue;
QtWayland::wl_compositor mCompositor;
struct wl_shm *mShm;
QThread *mEventThread;
diff --git a/src/client/qwaylandeventthread.cpp b/src/client/qwaylandeventthread.cpp
index e2e21c9e7..e0a3edcb8 100644
--- a/src/client/qwaylandeventthread.cpp
+++ b/src/client/qwaylandeventthread.cpp
@@ -80,13 +80,9 @@ void QWaylandEventThread::checkError() const
void QWaylandEventThread::readWaylandEvents()
{
- if (wl_display_dispatch(m_display) < 0) {
- checkError();
- m_readNotifier->setEnabled(false);
- emit fatalError();
- return;
+ if (wl_display_prepare_read(m_display) == 0) {
+ wl_display_read_events(m_display);
}
-
emit newEventsRead();
}
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
index 8170c39f1..0d20075f0 100644
--- a/src/client/qwaylandnativeinterface.cpp
+++ b/src/client/qwaylandnativeinterface.cpp
@@ -58,8 +58,6 @@ void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &re
if (lowerCaseResource == "display" || lowerCaseResource == "wl_display" || lowerCaseResource == "nativedisplay")
return m_integration->display()->wl_display();
- if (lowerCaseResource == "wl_event_queue")
- return m_integration->display()->wl_event_queue();
if (lowerCaseResource == "compositor")
return const_cast<wl_compositor *>(m_integration->display()->wl_compositor());
if (lowerCaseResource == "server_buffer_integration")