Make readEvents() non-blocking
authorPaul Olav Tvete <paul.tvete@nokia.com>
Mon, 11 Apr 2011 12:48:47 +0000 (14:48 +0200)
committerPaul Olav Tvete <paul.tvete@nokia.com>
Mon, 11 Apr 2011 12:55:17 +0000 (14:55 +0200)
Another event handler could empty the Wayland socket after the
socket notifier has triggered, but before the signal is delivered.
Since wl_display_iterate is blocking, we have to test whether there
is data available to avoid freezing the whole application.

Reviewed-by: Samuel
src/plugins/platforms/wayland/qwaylanddisplay.cpp
src/plugins/platforms/wayland/qwaylanddisplay.h
src/plugins/platforms/wayland/qwaylandwindow.cpp

index a6fdd46..eb9e791 100644 (file)
@@ -176,6 +176,30 @@ void QWaylandDisplay::flushRequests()
 
 void QWaylandDisplay::readEvents()
 {
+// verify that there is still data on the socket
+    fd_set fds;
+    FD_ZERO(&fds);
+    FD_SET(mFd, &fds);
+    fd_set nds;
+    FD_ZERO(&nds);
+    fd_set rs = fds;
+    fd_set ws = nds;
+    fd_set es = nds;
+    timeval timeout;
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 0;
+    int ret = ::select(mFd+1, &rs, &ws, &es, &timeout );
+
+    if (ret <= 0) {
+        //qDebug("QWaylandDisplay::readEvents() No data... blocking avoided");
+        return;
+    }
+
+    wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
+}
+
+void QWaylandDisplay::blockingReadEvents()
+{
     wl_display_iterate(mDisplay, WL_DISPLAY_READABLE);
 }
 
@@ -208,7 +232,7 @@ void QWaylandDisplay::waitForScreens()
 {
     flushRequests();
     while (mScreens.isEmpty())
-        readEvents();
+        blockingReadEvents();
 }
 
 void QWaylandDisplay::displayHandleGlobal(struct wl_display *display,
index e02767d..3ddbfb2 100644 (file)
@@ -86,6 +86,7 @@ public:
 public slots:
     void createNewScreen(struct wl_output *output, QRect geometry);
     void readEvents();
+    void blockingReadEvents();
     void flushRequests();
 
 private:
index d58b39d..7e94fb9 100644 (file)
@@ -154,5 +154,5 @@ void QWaylandWindow::waitForFrameSync()
 {
     mDisplay->flushRequests();
     while (mWaitingForFrameSync)
-        mDisplay->readEvents();
+        mDisplay->blockingReadEvents();
 }