refactor: allow exit event to provide an exit code

This commit is contained in:
Luiz Sardinha 2026-03-12 22:43:21 +01:00 committed by Chris Rizzitello
parent 71c25b3ab9
commit 9025ab8fb7
10 changed files with 45 additions and 15 deletions

View file

@ -21,6 +21,20 @@ public:
virtual ~EventData() = default; 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 //! Event
/*! /*!
\c Event holds an event type and a pointer to event data. It is movable, but not copyable \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()) { switch (event.getType()) {
using enum EventTypes; using enum EventTypes;
case Unknown: case Unknown:
case Quit:
case System: case System:
case Timer: case Timer:
break; break;

View file

@ -12,6 +12,7 @@
#include "base/EventQueueTimer.h" #include "base/EventQueueTimer.h"
#include "base/Log.h" #include "base/Log.h"
#include "base/SimpleEventQueueBuffer.h" #include "base/SimpleEventQueueBuffer.h"
#include "common/ExitCodes.h"
#include "mt/Lock.h" #include "mt/Lock.h"
#include "mt/Mutex.h" #include "mt/Mutex.h"
@ -44,7 +45,7 @@ EventQueue::~EventQueue()
ARCH->setSignalHandler(Arch::ThreadSignal::Terminate, nullptr, nullptr); ARCH->setSignalHandler(Arch::ThreadSignal::Terminate, nullptr, nullptr);
} }
void EventQueue::loop() int EventQueue::loop()
{ {
m_buffer->init(); m_buffer->init();
{ {
@ -67,6 +68,12 @@ void EventQueue::loop()
Event::deleteData(event); Event::deleteData(event);
getEvent(event); getEvent(event);
} }
int exitCode = s_exitSuccess;
auto *exitEvent = dynamic_cast<ExitEventData *>(event.getDataObject());
if (exitEvent != nullptr) {
exitCode = exitEvent->exitCode();
}
return exitCode;
} }
void EventQueue::adoptBuffer(IEventQueueBuffer *buffer) void EventQueue::adoptBuffer(IEventQueueBuffer *buffer)

View file

@ -35,7 +35,7 @@ public:
EventQueue &operator=(EventQueue &&) = delete; EventQueue &operator=(EventQueue &&) = delete;
// IEventQueue overrides // IEventQueue overrides
void loop() override; int loop() override;
void adoptBuffer(IEventQueueBuffer *) override; void adoptBuffer(IEventQueueBuffer *) override;
bool getEvent(Event &event, double timeout = -1.0) override; bool getEvent(Event &event, double timeout = -1.0) override;
bool dispatchEvent(const Event &event) override; bool dispatchEvent(const Event &event) override;

View file

@ -45,7 +45,7 @@ public:
/*! /*!
Dequeues and dispatches events until the kQuit event is found. Dequeues and dispatches events until the kQuit event is found.
*/ */
virtual void loop() = 0; virtual int loop() = 0;
//! Set the buffer //! Set the buffer
/*! /*!

View file

@ -12,9 +12,9 @@
#include "base/Log.h" #include "base/Log.h"
#include "base/LogOutputters.h" #include "base/LogOutputters.h"
#include "common/ExitCodes.h" #include "common/ExitCodes.h"
#include "common/PlatformInfo.h"
#include "common/Settings.h" #include "common/Settings.h"
#include "deskflow/DeskflowException.h" #include "deskflow/DeskflowException.h"
#include "mt/ThreadException.h"
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
@ -170,5 +170,8 @@ void App::handleScreenError() const
void App::runEventsLoop(const void *) void App::runEventsLoop(const void *)
{ {
m_events->loop(); int exitCode = m_events->loop();
if (exitCode != s_exitSuccess) {
throw ThreadExitException(new LoopErrorCode(exitCode));
}
} }

View file

@ -121,6 +121,14 @@ public:
protected: protected:
void runEventsLoop(const void *); void runEventsLoop(const void *);
struct LoopErrorCode
{
int m_errorCode;
LoopErrorCode(int errorCode) : m_errorCode(errorCode)
{
}
};
private: private:
void (*m_bye)(int); void (*m_bye)(int);
IEventQueue *m_events = nullptr; IEventQueue *m_events = nullptr;

View file

@ -327,15 +327,14 @@ int ClientApp::mainLoop()
// run event loop. if startClient() failed we're supposed to retry // run event loop. if startClient() failed we're supposed to retry
// later. the timer installed by startClient() will take care of // later. the timer installed by startClient() will take care of
// that. // that.
int exitCode = getEvents()->loop();
getEvents()->loop();
// close down // close down
LOG_DEBUG("stopping client"); LOG_DEBUG("stopping client");
stopClient(); stopClient();
LOG_NOTE("stopped client"); LOG_NOTE("stopped client");
return s_exitSuccess; return exitCode;
} }
int ClientApp::start() int ClientApp::start()

View file

@ -539,8 +539,7 @@ int ServerApp::mainLoop()
// run event loop. if startServer() failed we're supposed to retry // run event loop. if startServer() failed we're supposed to retry
// later. the timer installed by startServer() will take care of // later. the timer installed by startServer() will take care of
// that. // that.
int exitCode = getEvents()->loop();
getEvents()->loop();
// close down // close down
LOG_DEBUG("stopping server"); LOG_DEBUG("stopping server");
@ -549,7 +548,7 @@ int ServerApp::mainLoop()
cleanupServer(); cleanupServer();
LOG_NOTE("stopped server"); LOG_NOTE("stopped server");
return s_exitSuccess; return exitCode;
} }
void ServerApp::resetServer() void ServerApp::resetServer()

View file

@ -8,6 +8,7 @@
#pragma once #pragma once
#include "base/IEventQueue.h" #include "base/IEventQueue.h"
#include "common/ExitCodes.h"
class MockEventQueue : public IEventQueue class MockEventQueue : public IEventQueue
{ {
@ -27,9 +28,9 @@ public:
return true; return true;
} }
void loop() override int loop() override
{ {
// do nothing return s_exitSuccess;
} }
void adoptBuffer(IEventQueueBuffer *) override void adoptBuffer(IEventQueueBuffer *) override

View file

@ -14,7 +14,7 @@
class MockEventQueue : public IEventQueue class MockEventQueue : public IEventQueue
{ {
public: public:
MOCK_METHOD(void, loop, (), (override)); MOCK_METHOD(int, loop, (), (override));
MOCK_METHOD(EventQueueTimer *, newOneShotTimer, (double, void *), (override)); MOCK_METHOD(EventQueueTimer *, newOneShotTimer, (double, void *), (override));
MOCK_METHOD(EventQueueTimer *, newTimer, (double, void *), (override)); MOCK_METHOD(EventQueueTimer *, newTimer, (double, void *), (override));
MOCK_METHOD(bool, getEvent, (Event &, double), (override)); MOCK_METHOD(bool, getEvent, (Event &, double), (override));