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>
This commit is contained in:
Giulio Camuffo 2014-10-02 10:48:09 +03:00
parent 1a3d78d81f
commit 5984e1e5c1
4 changed files with 24 additions and 9 deletions

View File

@ -149,6 +149,7 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
init(registry); init(registry);
connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests())); connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests()));
connect(mEventThreadObject, &QWaylandEventThread::fatalError, this, &QWaylandDisplay::exitWithError);
mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this));
@ -167,8 +168,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
void QWaylandDisplay::flushRequests() void QWaylandDisplay::flushRequests()
{ {
if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) {
mEventThreadObject->checkErrorAndExit(); mEventThreadObject->checkError();
exitWithError();
}
wl_display_flush(mDisplay); wl_display_flush(mDisplay);
} }
@ -176,8 +179,15 @@ void QWaylandDisplay::flushRequests()
void QWaylandDisplay::blockingReadEvents() void QWaylandDisplay::blockingReadEvents()
{ {
if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) {
mEventThreadObject->checkErrorAndExit(); mEventThreadObject->checkError();
exitWithError();
}
}
void QWaylandDisplay::exitWithError()
{
::exit(1);
} }
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const

View File

@ -164,6 +164,7 @@ public slots:
private: private:
void waitForScreens(); void waitForScreens();
void exitWithError();
struct Listener { struct Listener {
RegistryListener listener; RegistryListener listener;

View File

@ -73,7 +73,7 @@ void QWaylandEventThread::displayConnect()
// ### be careful what you do, this function may also be called from other // ### be careful what you do, this function may also be called from other
// threads to clean up & exit. // threads to clean up & exit.
void QWaylandEventThread::checkErrorAndExit() void QWaylandEventThread::checkError() const
{ {
int ecode = wl_display_get_error(m_display); int ecode = wl_display_get_error(m_display);
if ((ecode == EPIPE || ecode == ECONNRESET)) { if ((ecode == EPIPE || ecode == ECONNRESET)) {
@ -82,13 +82,16 @@ void QWaylandEventThread::checkErrorAndExit()
} else { } else {
qErrnoWarning(ecode, "The Wayland connection experienced a fatal error"); qErrnoWarning(ecode, "The Wayland connection experienced a fatal error");
} }
::exit(1);
} }
void QWaylandEventThread::readWaylandEvents() void QWaylandEventThread::readWaylandEvents()
{ {
if (wl_display_dispatch(m_display) < 0) if (wl_display_dispatch(m_display) < 0) {
checkErrorAndExit(); checkError();
m_readNotifier->setEnabled(false);
emit fatalError();
return;
}
emit newEventsRead(); emit newEventsRead();
} }

View File

@ -63,7 +63,7 @@ public:
wl_display *display() const; wl_display *display() const;
void checkErrorAndExit(); void checkError() const;
private slots: private slots:
void readWaylandEvents(); void readWaylandEvents();
@ -72,6 +72,7 @@ private slots:
signals: signals:
void newEventsRead(); void newEventsRead();
void fatalError();
private: private: