From c7a8b70b4e9afef864652cf98a934d99d49bb36f Mon Sep 17 00:00:00 2001 From: Giulio Camuffo <giulio.camuffo@jollamobile.com> Date: Thu, 2 Oct 2014 10:48:09 +0300 Subject: [PATCH] Call ::exit() from the gui thread only ::exit() is not thread safe, so make sure to not call it more than one time, once from the gui thread and once from the wayland event thread. Change-Id: I80905c6d996cb827a5101ae6d6c9bc12a267ba71 Reviewed-by: Robin Burchell <robin.burchell@viroteck.net> --- src/client/qwaylanddisplay.cpp | 18 ++++++++++++++---- src/client/qwaylanddisplay_p.h | 1 + src/client/qwaylandeventthread.cpp | 11 +++++++---- src/client/qwaylandeventthread_p.h | 3 ++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 3eac985f6..8649a497c 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -149,6 +149,7 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) init(registry); connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests())); + connect(mEventThreadObject, &QWaylandEventThread::fatalError, this, &QWaylandDisplay::exitWithError); mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); @@ -167,8 +168,10 @@ QWaylandDisplay::~QWaylandDisplay(void) void QWaylandDisplay::flushRequests() { - if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) - mEventThreadObject->checkErrorAndExit(); + if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) { + mEventThreadObject->checkError(); + exitWithError(); + } wl_display_flush(mDisplay); } @@ -176,8 +179,15 @@ void QWaylandDisplay::flushRequests() void QWaylandDisplay::blockingReadEvents() { - if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) - mEventThreadObject->checkErrorAndExit(); + if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) { + mEventThreadObject->checkError(); + exitWithError(); + } +} + +void QWaylandDisplay::exitWithError() +{ + ::exit(1); } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index b0142004e..796c54756 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -164,6 +164,7 @@ public slots: private: void waitForScreens(); + void exitWithError(); struct Listener { RegistryListener listener; diff --git a/src/client/qwaylandeventthread.cpp b/src/client/qwaylandeventthread.cpp index b7266765e..22efd6a2a 100644 --- a/src/client/qwaylandeventthread.cpp +++ b/src/client/qwaylandeventthread.cpp @@ -73,7 +73,7 @@ void QWaylandEventThread::displayConnect() // ### be careful what you do, this function may also be called from other // threads to clean up & exit. -void QWaylandEventThread::checkErrorAndExit() +void QWaylandEventThread::checkError() const { int ecode = wl_display_get_error(m_display); if ((ecode == EPIPE || ecode == ECONNRESET)) { @@ -82,13 +82,16 @@ void QWaylandEventThread::checkErrorAndExit() } else { qErrnoWarning(ecode, "The Wayland connection experienced a fatal error"); } - ::exit(1); } void QWaylandEventThread::readWaylandEvents() { - if (wl_display_dispatch(m_display) < 0) - checkErrorAndExit(); + if (wl_display_dispatch(m_display) < 0) { + checkError(); + m_readNotifier->setEnabled(false); + emit fatalError(); + return; + } emit newEventsRead(); } diff --git a/src/client/qwaylandeventthread_p.h b/src/client/qwaylandeventthread_p.h index d51d627b9..2df4b05c2 100644 --- a/src/client/qwaylandeventthread_p.h +++ b/src/client/qwaylandeventthread_p.h @@ -63,7 +63,7 @@ public: wl_display *display() const; - void checkErrorAndExit(); + void checkError() const; private slots: void readWaylandEvents(); @@ -72,6 +72,7 @@ private slots: signals: void newEventsRead(); + void fatalError(); private: -- GitLab