UI: ServiceManager: Simplify processControlState()

This commit is contained in:
Nodir Temirkhodjaev 2024-06-06 19:11:55 +03:00
parent 93e44cef12
commit c7520740ba
3 changed files with 105 additions and 92 deletions

View File

@ -1,6 +1,7 @@
#include "servicemanager.h"
#include <QCoreApplication>
#include <QHash>
#include <QLoggingCategory>
#define WIN32_LEAN_AND_MEAN
@ -20,6 +21,101 @@ namespace {
const QLoggingCategory LC("manager.service");
quint32 processControlPauseState(
ServiceManager *serviceManager, quint32 /*code*/, quint32 /*eventType*/)
{
if (!serviceManager->acceptPauseContinue())
return 0;
qCDebug(LC) << "Pause due service control";
emit serviceManager->pauseRequested();
return SERVICE_PAUSED;
}
quint32 processControlContinueState(
ServiceManager *serviceManager, quint32 /*code*/, quint32 /*eventType*/)
{
if (!serviceManager->acceptPauseContinue())
return 0;
qCDebug(LC) << "Continue due service control";
emit serviceManager->continueRequested();
return SERVICE_RUNNING;
}
quint32 processControlStopState(
ServiceManager *serviceManager, quint32 /*code*/, quint32 /*eventType*/)
{
return serviceManager->acceptStop() ? SERVICE_STOP_PENDING : 0;
}
quint32 processControlShutdownState(
ServiceManager *serviceManager, quint32 code, quint32 /*eventType*/)
{
const bool restarting = (code == ServiceControlStopRestarting);
if (restarting || code == ServiceControlStopUninstall) {
emit serviceManager->stopRestartingRequested(restarting);
}
return SERVICE_STOP_PENDING;
}
quint32 processControlDeviceEvent(
ServiceManager *serviceManager, quint32 /*code*/, quint32 eventType)
{
if (ServiceManagerIface::isDeviceEvent(eventType)) {
emit serviceManager->driveListChanged();
}
return 0;
}
enum ServiceControlHandlerCode : qint8 {
ControlHandlerNone = -1,
ControlHandlerPause = 0,
ControlHandlerContinue,
ControlHandlerStop,
ControlHandlerShutdown,
ControlHandlerDeviceEvent,
};
static const QHash<quint8, ServiceControlHandlerCode> g_controlHandlerCodes = {
{ SERVICE_CONTROL_PAUSE, ControlHandlerPause },
{ SERVICE_CONTROL_CONTINUE, ControlHandlerContinue },
{ SERVICE_CONTROL_STOP, ControlHandlerStop },
{ ServiceControlStop, ControlHandlerShutdown },
{ ServiceControlStopRestarting, ControlHandlerShutdown },
{ ServiceControlStopUninstall, ControlHandlerShutdown },
{ SERVICE_CONTROL_SHUTDOWN, ControlHandlerShutdown },
{ SERVICE_CONTROL_DEVICEEVENT, ControlHandlerDeviceEvent },
};
using controlHandler_func = quint32 (*)(
ServiceManager *serviceManager, quint32 code, quint32 eventType);
static const controlHandler_func controlHandler_funcList[] = {
&processControlPauseState, // ControlHandlerPause,
&processControlContinueState, // ControlHandlerContinue,
&processControlStopState, // ControlHandlerStop,
&processControlShutdownState, // ControlHandlerShutdown,
&processControlDeviceEvent, // ControlHandlerDeviceEvent,
};
inline quint32 processControlState(ServiceManager *serviceManager, quint32 code, quint32 eventType)
{
const auto handlerCode = g_controlHandlerCodes.value(code, ControlHandlerNone);
if (handlerCode == ControlHandlerNone)
return 0;
const controlHandler_func func = controlHandler_funcList[handlerCode];
return func(serviceManager, code, eventType);
}
}
ServiceManager::ServiceManager(QObject *parent) : QObject(parent) { }
@ -85,7 +181,7 @@ const wchar_t *ServiceManager::serviceName() const
void ServiceManager::processControl(quint32 code, quint32 eventType)
{
const auto state = processControlState(code, eventType);
const auto state = processControlState(this, code, eventType);
if (state == SERVICE_STOP_PENDING) {
OsUtil::quit("service control"); // it's threadsafe
@ -94,82 +190,6 @@ void ServiceManager::processControl(quint32 code, quint32 eventType)
reportStatus(state);
}
quint32 ServiceManager::processControlState(quint32 code, quint32 eventType)
{
switch (code) {
case SERVICE_CONTROL_PAUSE: {
return processControlPauseState();
} break;
case SERVICE_CONTROL_CONTINUE: {
return processControlContinueState();
} break;
case SERVICE_CONTROL_STOP: {
return processControlStopState();
} break;
case ServiceControlStop:
case ServiceControlStopRestarting:
case ServiceControlStopUninstall:
case SERVICE_CONTROL_SHUTDOWN: {
return processControlShutdownState(code);
} break;
case SERVICE_CONTROL_DEVICEEVENT: {
processControlDeviceEvent(eventType);
} break;
}
return 0;
}
quint32 ServiceManager::processControlPauseState()
{
if (!acceptPauseContinue())
return 0;
qCDebug(LC) << "Pause due service control";
emit pauseRequested();
return SERVICE_PAUSED;
}
quint32 ServiceManager::processControlContinueState()
{
if (!acceptPauseContinue())
return 0;
qCDebug(LC) << "Continue due service control";
emit continueRequested();
return SERVICE_RUNNING;
}
quint32 ServiceManager::processControlStopState()
{
return acceptStop() ? SERVICE_STOP_PENDING : 0;
}
quint32 ServiceManager::processControlShutdownState(quint32 code)
{
const bool restarting = (code == ServiceControlStopRestarting);
if (restarting || code == ServiceControlStopUninstall) {
emit stopRestartingRequested(restarting);
}
return SERVICE_STOP_PENDING;
}
void ServiceManager::processControlDeviceEvent(quint32 eventType)
{
if (isDeviceEvent(eventType)) {
emit driveListChanged();
}
}
void ServiceManager::restart()
{
connect(qApp, &QObject::destroyed, [] { OsUtil::startService(APP_BASE "Svc"); });

View File

@ -23,6 +23,9 @@ public:
bool controlEnabled() const { return m_controlEnabled; }
void setControlEnabled(bool v);
bool acceptStop() const override { return controlEnabled(); }
bool acceptPauseContinue() const override { return controlEnabled(); }
void initialize(qintptr hstatus) override;
const wchar_t *serviceName() const override;
@ -41,19 +44,9 @@ protected:
void setupControlManager();
void setupConfManager();
bool acceptStop() const override { return controlEnabled(); }
bool acceptPauseContinue() const override { return controlEnabled(); }
private:
void setupByConf(const IniOptions &ini);
quint32 processControlState(quint32 code, quint32 eventType);
quint32 processControlPauseState();
quint32 processControlContinueState();
quint32 processControlStopState();
quint32 processControlShutdownState(quint32 code);
void processControlDeviceEvent(quint32 eventType);
private:
bool m_controlEnabled = false;
};

View File

@ -9,6 +9,9 @@ public:
ServiceManagerIface() = default;
virtual ~ServiceManagerIface() = default;
virtual bool acceptStop() const { return true; }
virtual bool acceptPauseContinue() const { return true; }
virtual void initialize(qintptr hstatus);
void registerDeviceNotification();
@ -18,15 +21,12 @@ public:
virtual void processControl(quint32 code, quint32 eventType) = 0;
protected:
virtual bool acceptStop() const { return true; }
virtual bool acceptPauseContinue() const { return true; }
static bool isDeviceEvent(quint32 eventType);
protected:
void setupAcceptedControls();
static void reportStatus(quint32 code = 0);
static bool isDeviceEvent(quint32 eventType);
};
#endif // SERVICEMANAGERIFACE_H