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>
This commit is contained in:
parent
837c740cd6
commit
0b71d61d37
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user