From 85894201917e1d1c8d3d4da94a867ee8c8c1a60c Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Wed, 28 Nov 2018 17:04:59 +0800 Subject: [PATCH 03/15] qwaylanddisplay: Refactor flushRequests() for multiple readers Cancel reading when no events polled, since the other clients, e.g. waylandsink, might already read the events before us. Signed-off-by: Jeffy Chen --- src/client/qwaylanddisplay.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index fe094f6f..ba4ce931 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -84,6 +84,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -214,24 +215,38 @@ void QWaylandDisplay::checkError() const void QWaylandDisplay::flushRequests() { - if (wl_display_prepare_read(mDisplay) == 0) { + struct pollfd fd; + int ret; + + // 1. Prepare exclusive reading + while (wl_display_prepare_read(mDisplay) != 0) + wl_display_dispatch_pending(mDisplay); + + // 2. Nonblock event reading + fd.fd = wl_display_get_fd(mDisplay); + fd.events = POLLIN | POLLERR | POLLHUP; + ret = poll(&fd, 1, 0); + if (ret > 0 && fd.revents & POLLIN) wl_display_read_events(mDisplay); - } + else + wl_display_cancel_read(mDisplay); - if (wl_display_dispatch_pending(mDisplay) < 0) + // 3. Error check + if (wl_display_get_error(mDisplay) != 0) checkError(); + // 4. Dispatch events on our queues + wl_display_dispatch_pending(mDisplay); + { QReadLocker locker(&m_frameQueueLock); for (const FrameQueue &q : mExternalQueues) { QMutexLocker locker(q.mutex); - while (wl_display_prepare_read_queue(mDisplay, q.queue) != 0) - wl_display_dispatch_queue_pending(mDisplay, q.queue); - wl_display_read_events(mDisplay); wl_display_dispatch_queue_pending(mDisplay, q.queue); } } + // 5. Final flush wl_display_flush(mDisplay); } -- 2.20.1