From 9025ab8fb780480389db43c20970a3ae0208834a Mon Sep 17 00:00:00 2001 From: Luiz Sardinha Date: Thu, 12 Mar 2026 22:43:21 +0100 Subject: [PATCH] refactor: allow exit event to provide an exit code --- src/lib/base/Event.h | 15 ++++++++++++++- src/lib/base/EventQueue.cpp | 9 ++++++++- src/lib/base/EventQueue.h | 2 +- src/lib/base/IEventQueue.h | 2 +- src/lib/deskflow/App.cpp | 7 +++++-- src/lib/deskflow/App.h | 8 ++++++++ src/lib/deskflow/ClientApp.cpp | 5 ++--- src/lib/deskflow/ServerApp.cpp | 5 ++--- src/unittests/deskflow/MockEventQueue.h | 5 +++-- .../legacytests/mock/deskflow/MockEventQueue.h | 2 +- 10 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/lib/base/Event.h b/src/lib/base/Event.h index e349c4ce1..9bf95a047 100644 --- a/src/lib/base/Event.h +++ b/src/lib/base/Event.h @@ -21,6 +21,20 @@ public: virtual ~EventData() = default; }; +class ExitEventData : public EventData +{ +public: + ExitEventData(int exitCode) : m_exitCode(exitCode) {}; + virtual ~ExitEventData() = default; + int exitCode() + { + return m_exitCode; + } + +private: + int m_exitCode; +}; + //! Event /*! \c Event holds an event type and a pointer to event data. It is movable, but not copyable @@ -77,7 +91,6 @@ public: switch (event.getType()) { using enum EventTypes; case Unknown: - case Quit: case System: case Timer: break; diff --git a/src/lib/base/EventQueue.cpp b/src/lib/base/EventQueue.cpp index b91be2112..4eaf34f93 100644 --- a/src/lib/base/EventQueue.cpp +++ b/src/lib/base/EventQueue.cpp @@ -12,6 +12,7 @@ #include "base/EventQueueTimer.h" #include "base/Log.h" #include "base/SimpleEventQueueBuffer.h" +#include "common/ExitCodes.h" #include "mt/Lock.h" #include "mt/Mutex.h" @@ -44,7 +45,7 @@ EventQueue::~EventQueue() ARCH->setSignalHandler(Arch::ThreadSignal::Terminate, nullptr, nullptr); } -void EventQueue::loop() +int EventQueue::loop() { m_buffer->init(); { @@ -67,6 +68,12 @@ void EventQueue::loop() Event::deleteData(event); getEvent(event); } + int exitCode = s_exitSuccess; + auto *exitEvent = dynamic_cast(event.getDataObject()); + if (exitEvent != nullptr) { + exitCode = exitEvent->exitCode(); + } + return exitCode; } void EventQueue::adoptBuffer(IEventQueueBuffer *buffer) diff --git a/src/lib/base/EventQueue.h b/src/lib/base/EventQueue.h index e40a99f23..4d9b6c35e 100644 --- a/src/lib/base/EventQueue.h +++ b/src/lib/base/EventQueue.h @@ -35,7 +35,7 @@ public: EventQueue &operator=(EventQueue &&) = delete; // IEventQueue overrides - void loop() override; + int loop() override; void adoptBuffer(IEventQueueBuffer *) override; bool getEvent(Event &event, double timeout = -1.0) override; bool dispatchEvent(const Event &event) override; diff --git a/src/lib/base/IEventQueue.h b/src/lib/base/IEventQueue.h index 69cdf2597..f06b5a616 100644 --- a/src/lib/base/IEventQueue.h +++ b/src/lib/base/IEventQueue.h @@ -45,7 +45,7 @@ public: /*! Dequeues and dispatches events until the kQuit event is found. */ - virtual void loop() = 0; + virtual int loop() = 0; //! Set the buffer /*! diff --git a/src/lib/deskflow/App.cpp b/src/lib/deskflow/App.cpp index 6ae41e161..c75e52072 100644 --- a/src/lib/deskflow/App.cpp +++ b/src/lib/deskflow/App.cpp @@ -12,9 +12,9 @@ #include "base/Log.h" #include "base/LogOutputters.h" #include "common/ExitCodes.h" -#include "common/PlatformInfo.h" #include "common/Settings.h" #include "deskflow/DeskflowException.h" +#include "mt/ThreadException.h" #if defined(Q_OS_WIN) #include "base/IEventQueue.h" @@ -170,5 +170,8 @@ void App::handleScreenError() const void App::runEventsLoop(const void *) { - m_events->loop(); + int exitCode = m_events->loop(); + if (exitCode != s_exitSuccess) { + throw ThreadExitException(new LoopErrorCode(exitCode)); + } } diff --git a/src/lib/deskflow/App.h b/src/lib/deskflow/App.h index dc8c6e811..eb4dc907c 100644 --- a/src/lib/deskflow/App.h +++ b/src/lib/deskflow/App.h @@ -121,6 +121,14 @@ public: protected: void runEventsLoop(const void *); + struct LoopErrorCode + { + int m_errorCode; + LoopErrorCode(int errorCode) : m_errorCode(errorCode) + { + } + }; + private: void (*m_bye)(int); IEventQueue *m_events = nullptr; diff --git a/src/lib/deskflow/ClientApp.cpp b/src/lib/deskflow/ClientApp.cpp index 702ad9763..c0464de84 100644 --- a/src/lib/deskflow/ClientApp.cpp +++ b/src/lib/deskflow/ClientApp.cpp @@ -327,15 +327,14 @@ int ClientApp::mainLoop() // run event loop. if startClient() failed we're supposed to retry // later. the timer installed by startClient() will take care of // that. - - getEvents()->loop(); + int exitCode = getEvents()->loop(); // close down LOG_DEBUG("stopping client"); stopClient(); LOG_NOTE("stopped client"); - return s_exitSuccess; + return exitCode; } int ClientApp::start() diff --git a/src/lib/deskflow/ServerApp.cpp b/src/lib/deskflow/ServerApp.cpp index 4efe27f10..d5caf7a03 100644 --- a/src/lib/deskflow/ServerApp.cpp +++ b/src/lib/deskflow/ServerApp.cpp @@ -539,8 +539,7 @@ int ServerApp::mainLoop() // run event loop. if startServer() failed we're supposed to retry // later. the timer installed by startServer() will take care of // that. - - getEvents()->loop(); + int exitCode = getEvents()->loop(); // close down LOG_DEBUG("stopping server"); @@ -549,7 +548,7 @@ int ServerApp::mainLoop() cleanupServer(); LOG_NOTE("stopped server"); - return s_exitSuccess; + return exitCode; } void ServerApp::resetServer() diff --git a/src/unittests/deskflow/MockEventQueue.h b/src/unittests/deskflow/MockEventQueue.h index f15db02da..3f220bd44 100644 --- a/src/unittests/deskflow/MockEventQueue.h +++ b/src/unittests/deskflow/MockEventQueue.h @@ -8,6 +8,7 @@ #pragma once #include "base/IEventQueue.h" +#include "common/ExitCodes.h" class MockEventQueue : public IEventQueue { @@ -27,9 +28,9 @@ public: return true; } - void loop() override + int loop() override { - // do nothing + return s_exitSuccess; } void adoptBuffer(IEventQueueBuffer *) override diff --git a/src/unittests/legacytests/mock/deskflow/MockEventQueue.h b/src/unittests/legacytests/mock/deskflow/MockEventQueue.h index 14e4d2b84..28328ebf9 100644 --- a/src/unittests/legacytests/mock/deskflow/MockEventQueue.h +++ b/src/unittests/legacytests/mock/deskflow/MockEventQueue.h @@ -14,7 +14,7 @@ class MockEventQueue : public IEventQueue { public: - MOCK_METHOD(void, loop, (), (override)); + MOCK_METHOD(int, loop, (), (override)); MOCK_METHOD(EventQueueTimer *, newOneShotTimer, (double, void *), (override)); MOCK_METHOD(EventQueueTimer *, newTimer, (double, void *), (override)); MOCK_METHOD(bool, getEvent, (Event &, double), (override));