From 426d60a6992259ca80431c59e916073cc31f5261 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 3 Oct 2008 01:30:27 +0200 Subject: Callback-basierte SystemBackends f?r h?here Flexibilit?t --- src/Common/Backends/SystemBackendPosix.cpp | 2 +- src/Common/Backends/SystemBackendPosix.h | 7 +-- src/Common/Backends/SystemBackendProc.cpp | 52 ++++++++++--------- src/Common/Backends/SystemBackendProc.h | 6 +-- .../RequestHandlers/StatusRequestHandler.cpp | 29 ++++++++--- src/Common/RequestHandlers/StatusRequestHandler.h | 36 ++++++++++++- src/Common/SystemBackend.cpp | 60 +++++++++++----------- src/Common/SystemBackend.h | 51 +++++------------- .../RequestHandlers/CommandRequestHandler.cpp | 23 +++++---- src/Daemon/RequestHandlers/CommandRequestHandler.h | 4 ++ 10 files changed, 155 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/Common/Backends/SystemBackendPosix.cpp b/src/Common/Backends/SystemBackendPosix.cpp index b1e088d..3ddf67d 100644 --- a/src/Common/Backends/SystemBackendPosix.cpp +++ b/src/Common/Backends/SystemBackendPosix.cpp @@ -69,7 +69,7 @@ void SystemBackendPosix::childHandler(int) { setChildHandler(); } -bool SystemBackendPosix::exec(sigc::slot resultHandler, const std::string &filename, const std::vector &argv, const std::vector &env) { +bool SystemBackendPosix::exec(const sigc::slot& resultHandler, const std::string &filename, const std::vector &argv, const std::vector &env) { pid_t pid; char **argvp, **envp; diff --git a/src/Common/Backends/SystemBackendPosix.h b/src/Common/Backends/SystemBackendPosix.h index 9efd59f..4a2c572 100644 --- a/src/Common/Backends/SystemBackendPosix.h +++ b/src/Common/Backends/SystemBackendPosix.h @@ -28,6 +28,7 @@ #include #include +#include namespace Mad { namespace Common { @@ -47,8 +48,8 @@ class SystemBackendPosix : public SystemBackend { } protected: - virtual bool doShutdown() {return exec(sigc::slot(), "/sbin/halt");} - virtual bool doReboot() {return exec(sigc::slot(), "/sbin/reboot");} + virtual bool doShutdown(const sigc::slot &callback) {return exec(sigc::hide(callback), "/sbin/halt");} + virtual bool doReboot(const sigc::slot &callback) {return exec(sigc::hide(callback), "/sbin/reboot");} public: ~SystemBackendPosix(); @@ -61,7 +62,7 @@ class SystemBackendPosix : public SystemBackend { SystemBackend::unregisterBackend(&backend); } - static bool exec(sigc::slot resultHandler, const std::string &filename, const std::vector &argv = std::vector(), + static bool exec(const sigc::slot &resultHandler, const std::string &filename, const std::vector &argv = std::vector(), const std::vector &env = std::vector()); }; diff --git a/src/Common/Backends/SystemBackendProc.cpp b/src/Common/Backends/SystemBackendProc.cpp index 37bfaf3..134998f 100644 --- a/src/Common/Backends/SystemBackendProc.cpp +++ b/src/Common/Backends/SystemBackendProc.cpp @@ -28,37 +28,37 @@ namespace Backends { SystemBackendProc SystemBackendProc::backend; -SystemBackend::UptimeInfo SystemBackendProc::uptimeInfo() { - UptimeInfo uptime = {0, 0}; +bool SystemBackendProc::uptimeInfo(const sigc::slot &callback) { + unsigned long uptime = 0, idleTime = 0; uptimeFile.seekg(0, std::ios::beg); if(!uptimeFile.good()) - return uptime; + return false; float f; uptimeFile >> f; if(!uptimeFile.good()) - return uptime; + return false; - uptime.uptime = (unsigned long)f; + uptime = (unsigned long)f; uptimeFile >> f; - if(!uptimeFile.good()) - return uptime; + if(uptimeFile.good()) + idleTime = (unsigned long)f; - uptime.idleTime = (unsigned long)f; + callback(uptime, idleTime); - return uptime; + return true; } -SystemBackend::MemoryInfo SystemBackendProc::memoryInfo() { - MemoryInfo memInfo = {0, 0, 0, 0}; +bool SystemBackendProc::memoryInfo(const sigc::slot &callback) { + unsigned long totalMem = 0, freeMem = 0, totalSwap = 0, freeSwap = 0; meminfoFile.seekg(0, std::ios::beg); if(!meminfoFile.good()) - return memInfo; + return false; while(!meminfoFile.eof() && meminfoFile.good()) { std::string line; @@ -69,42 +69,46 @@ SystemBackend::MemoryInfo SystemBackendProc::memoryInfo() { if(std::sscanf(line.c_str(), "%s %lu", name, &value) == 2) { if(std::strcmp(name, "MemTotal:") == 0) - memInfo.totalMem = value; + totalMem = value; else if(std::strcmp(name, "MemFree:") == 0) - memInfo.freeMem = value; + freeMem = value; else if(std::strcmp(name, "SwapTotal:") == 0) - memInfo.totalSwap = value; + totalSwap = value; else if(std::strcmp(name, "SwapFree:") == 0) - memInfo.freeSwap = value; + freeSwap = value; } delete [] name; - if(memInfo.totalMem && memInfo.freeMem && memInfo.totalSwap && memInfo.freeSwap) + if(totalMem && freeMem && totalSwap && freeSwap) break; } + callback(totalMem, freeMem, totalSwap, freeSwap); - return memInfo; + return true; } -SystemBackend::LoadInfo SystemBackendProc::loadInfo() { - LoadInfo loadInfo = {0, 0, 0, 0, 0}; +bool SystemBackendProc::loadInfo(const sigc::slot &callback) { + unsigned long currentLoad = 0, nProcesses = 0; + float loadAvg1 = 0, loadAvg5 = 0, loadAvg15 = 0; loadFile.seekg(0, std::ios::beg); if(!loadFile.good()) - return loadInfo; + return false; std::string line; std::getline(loadFile, line); if(line.empty()) - return loadInfo; + return false; + + std::sscanf(line.c_str(), "%f %f %f %lu/%lu", &loadAvg1, &loadAvg5, &loadAvg15, ¤tLoad, &nProcesses); - std::sscanf(line.c_str(), "%f %f %f %lu/%lu", &loadInfo.loadAvg1, &loadInfo.loadAvg5, &loadInfo.loadAvg15, &loadInfo.currentLoad, &loadInfo.nProcesses); + callback(currentLoad, nProcesses, loadAvg1, loadAvg5, loadAvg15); - return loadInfo; + return true; } } diff --git a/src/Common/Backends/SystemBackendProc.h b/src/Common/Backends/SystemBackendProc.h index 619c996..79ff6c5 100644 --- a/src/Common/Backends/SystemBackendProc.h +++ b/src/Common/Backends/SystemBackendProc.h @@ -47,9 +47,9 @@ class SystemBackendProc : public SystemBackend { SystemBackend::unregisterBackend(&backend); } - virtual UptimeInfo uptimeInfo(); - virtual MemoryInfo memoryInfo(); - virtual LoadInfo loadInfo(); + virtual bool uptimeInfo(const sigc::slot &callback); + virtual bool memoryInfo(const sigc::slot &callback); + virtual bool loadInfo(const sigc::slot &callback); }; } diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp index dbdf9e1..8494fee 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.cpp +++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp @@ -28,10 +28,10 @@ namespace Mad { namespace Common { namespace RequestHandlers { -void StatusRequestHandler::handlePacket(Net::Connection *connection, const Net::Packet &packet) { +void StatusRequestHandler::handlePacket(Net::Connection *con, const Net::Packet &packet) { if(packet.getType() != Net::Packet::STATUS) { Logger::log(Logger::ERROR, "Received an unexpected packet."); - connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Exception(Exception::UNEXPECTED_PACKET))); + con->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Exception(Exception::UNEXPECTED_PACKET))); signalFinished().emit(); return; @@ -39,12 +39,27 @@ void StatusRequestHandler::handlePacket(Net::Connection *connection, const Net:: // TODO Require authentication - SystemBackend::UptimeInfo uptimeInfo = SystemBackend::getUptimeInfo(); - SystemBackend::MemoryInfo memInfo = SystemBackend::getMemoryInfo(); - SystemBackend::LoadInfo loadInfo = SystemBackend::getLoadInfo(); + connection = con; + requestId = packet.getRequestId(); - connection->send(Net::Packets::HostStatusPacket(Net::Packet::OK, packet.getRequestId(), uptimeInfo.uptime, uptimeInfo.idleTime, - memInfo.totalMem, memInfo.freeMem, memInfo.totalSwap, memInfo.freeSwap, loadInfo.currentLoad, loadInfo.nProcesses, loadInfo.loadAvg1, loadInfo.loadAvg5, loadInfo.loadAvg15)); + if(!SystemBackend::getUptimeInfo(sigc::mem_fun(this, &StatusRequestHandler::uptimeHandler))) + needUptime = false; + if(!SystemBackend::getMemoryInfo(sigc::mem_fun(this, &StatusRequestHandler::memoryHandler))) + needMemory = false; + if(!SystemBackend::getLoadInfo(sigc::mem_fun(this, &StatusRequestHandler::loadHandler))) + needLoad = false; + + send(); +} + +void StatusRequestHandler::send() { + if(needUptime || needMemory || needLoad || sent) + return; + + connection->send(Net::Packets::HostStatusPacket(Net::Packet::OK, requestId, uptime, idleTime, + totalMem, freeMem, totalSwap, freeSwap, currentLoad, nProcesses, loadAvg1, loadAvg5, loadAvg15)); + + sent = true; signalFinished().emit(); } diff --git a/src/Common/RequestHandlers/StatusRequestHandler.h b/src/Common/RequestHandlers/StatusRequestHandler.h index c5dcbf7..fd907de 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.h +++ b/src/Common/RequestHandlers/StatusRequestHandler.h @@ -21,17 +21,51 @@ #define MAD_COMMON_REQUESTHANDLERS_STATUSREQUESTHANDLER_H_ #include "../RequestHandler.h" +#include namespace Mad { namespace Common { namespace RequestHandlers { class StatusRequestHandler : public RequestHandler { + private: + Net::Connection *connection; + uint16_t requestId; + + bool needUptime, needMemory, needLoad, sent; + + unsigned long uptime, idleTime; + unsigned long totalMem, freeMem, totalSwap, freeSwap; + unsigned long currentLoad, nProcesses; + float loadAvg1, loadAvg5, loadAvg15; + + void uptimeHandler(unsigned long uptime0, unsigned long idleTime0) { + uptime = uptime0; idleTime = idleTime0; + needUptime = false; + send(); + } + + void memoryHandler(unsigned long totalMem0, unsigned long freeMem0, unsigned long totalSwap0, unsigned long freeSwap0) { + totalMem = totalMem0; freeMem = freeMem0; totalSwap = totalSwap0; freeSwap = freeSwap0; + needMemory = false; + send(); + } + + void loadHandler(unsigned long currentLoad0, unsigned long nProcesses0, float loadAvg10, float loadAvg50, float loadAvg150) { + currentLoad = currentLoad0; nProcesses = nProcesses0; loadAvg1 = loadAvg10; loadAvg5 = loadAvg50; loadAvg15 = loadAvg150; + needLoad = false; + send(); + } + + void send(); + protected: virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); public: - StatusRequestHandler() {} + StatusRequestHandler() : needUptime(true), needMemory(true), needLoad(true), sent(false), + uptime(0), idleTime(0), totalMem(0), freeMem(0), totalSwap(0), freeSwap(0), + currentLoad(0), nProcesses(0), loadAvg1(0), loadAvg5(0), loadAvg15(0) {} }; } diff --git a/src/Common/SystemBackend.cpp b/src/Common/SystemBackend.cpp index c017356..06a2898 100644 --- a/src/Common/SystemBackend.cpp +++ b/src/Common/SystemBackend.cpp @@ -25,49 +25,49 @@ namespace Common { std::set SystemBackend::backends; -SystemBackend::UptimeInfo SystemBackend::getUptimeInfo() { - UptimeInfo ret = {0, 0}; +bool SystemBackend::getUptimeInfo(const sigc::slot &callback) { + for(std::set::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->uptimeInfo(callback)) + return true; + } - for(std::set::iterator backend = backends.begin(); backend != backends.end() && ret.uptime == 0; ++backend) - ret = (*backend)->uptimeInfo(); - - return ret; + return false; } -SystemBackend::MemoryInfo SystemBackend::getMemoryInfo() { - MemoryInfo ret = {0, 0, 0, 0}; - - for(std::set::iterator backend = backends.begin(); backend != backends.end() && ret.totalMem == 0; ++backend) - ret = (*backend)->memoryInfo(); +bool SystemBackend::getMemoryInfo(const sigc::slot &callback) { + for(std::set::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->memoryInfo(callback)) + return true; + } - return ret; + return false; } -SystemBackend::LoadInfo SystemBackend::getLoadInfo() { - LoadInfo ret = {0, 0, 0, 0, 0}; - - for(std::set::iterator backend = backends.begin(); backend != backends.end() && ret.currentLoad == 0 && ret.loadAvg1 == 0 && ret.nProcesses == 0; ++backend) - ret = (*backend)->loadInfo(); +bool SystemBackend::getLoadInfo(const sigc::slot &callback) { + for(std::set::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->loadInfo(callback)) + return true; + } - return ret; + return false; } -bool SystemBackend::shutdown() { - bool ret = false; +bool SystemBackend::shutdown(const sigc::slot &callback) { + for(std::set::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->doShutdown(callback)) + return true; + } - for(std::set::iterator backend = backends.begin(); backend != backends.end() && !ret; ++backend) - ret = (*backend)->doShutdown(); - - return ret; + return false; } -bool SystemBackend::reboot() { - bool ret = false; - - for(std::set::iterator backend = backends.begin(); backend != backends.end() && !ret; ++backend) - ret = (*backend)->doReboot(); +bool SystemBackend::reboot(const sigc::slot &callback) { + for(std::set::iterator backend = backends.begin(); backend != backends.end(); ++backend) { + if((*backend)->doReboot(callback)) + return true; + } - return ret; + return false; } } diff --git a/src/Common/SystemBackend.h b/src/Common/SystemBackend.h index d9506a9..c8eee69 100644 --- a/src/Common/SystemBackend.h +++ b/src/Common/SystemBackend.h @@ -21,32 +21,12 @@ #define MAD_COMMON_SYSTEMBACKEND_H_ #include +#include namespace Mad { namespace Common { class SystemBackend { - public: - struct UptimeInfo { - unsigned long uptime; - unsigned long idleTime; - }; - - struct MemoryInfo { - unsigned long totalMem; - unsigned long freeMem; - unsigned long totalSwap; - unsigned long freeSwap; - }; - - struct LoadInfo { - unsigned long currentLoad; - unsigned long nProcesses; - float loadAvg1; - float loadAvg5; - float loadAvg15; - }; - private: struct Compare { bool operator() (const SystemBackend *b1, const SystemBackend *b2) { @@ -70,23 +50,20 @@ class SystemBackend { backends.erase(backend); } - virtual UptimeInfo uptimeInfo() { - UptimeInfo ret = {0, 0}; - return ret; + virtual bool uptimeInfo(const sigc::slot&) { + return false; } - virtual MemoryInfo memoryInfo() { - MemoryInfo ret = {0, 0, 0, 0}; - return ret; + virtual bool memoryInfo(const sigc::slot&) { + return false; } - virtual LoadInfo loadInfo() { - LoadInfo ret = {0, 0, 0, 0, 0}; - return ret; + virtual bool loadInfo(const sigc::slot&) { + return false; } - virtual bool doShutdown() {return false;} - virtual bool doReboot() {return false;} + virtual bool doShutdown(const sigc::slot&) {return false;} + virtual bool doReboot(const sigc::slot&) {return false;} virtual int getPriority() const { return 0; @@ -95,12 +72,12 @@ class SystemBackend { public: virtual ~SystemBackend() {} - static UptimeInfo getUptimeInfo(); - static MemoryInfo getMemoryInfo(); - static LoadInfo getLoadInfo(); + static bool getUptimeInfo(const sigc::slot &callback); + static bool getMemoryInfo(const sigc::slot &callback); + static bool getLoadInfo(const sigc::slot &callback); - static bool shutdown(); - static bool reboot(); + static bool shutdown(const sigc::slot &callback); + static bool reboot(const sigc::slot &callback); }; } diff --git a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp index e49b0f5..c6750ba 100644 --- a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp +++ b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp @@ -24,6 +24,8 @@ #include #include +#include + namespace Mad { namespace Daemon { namespace RequestHandlers { @@ -31,15 +33,17 @@ namespace RequestHandlers { void CommandRequestHandler::handlePacket(Net::Connection *connection, const Net::Packet &packet) { // TODO Require authentication - bool ret = false; - switch(packet.getType()) { case Net::Packet::COMMAND_SHUTDOWN: - ret = Common::SystemBackend::shutdown(); + if(Common::SystemBackend::shutdown(sigc::bind(sigc::mem_fun(this, &CommandRequestHandler::sendReply), connection, packet.getRequestId()))) + return; + break; case Net::Packet::COMMAND_REBOOT: - ret = Common::SystemBackend::reboot(); + if(Common::SystemBackend::reboot(sigc::bind(sigc::mem_fun(this, &CommandRequestHandler::sendReply), connection, packet.getRequestId()))) + return; + break; default: @@ -50,12 +54,13 @@ void CommandRequestHandler::handlePacket(Net::Connection *connection, const Net: return; } - if(ret) - connection->send(Net::Packet(Net::Packet::OK, packet.getRequestId())); - else { - connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Common::Exception(Common::Exception::NOT_IMPLEMENTED))); - } + connection->send(Net::Packets::ErrorPacket(Net::Packet::ERROR, packet.getRequestId(), Common::Exception(Common::Exception::NOT_IMPLEMENTED))); + + signalFinished().emit(); +} +void CommandRequestHandler::sendReply(Net::Connection *connection, uint16_t requestId) { + connection->send(Net::Packet(Net::Packet::OK, requestId)); signalFinished().emit(); } diff --git a/src/Daemon/RequestHandlers/CommandRequestHandler.h b/src/Daemon/RequestHandlers/CommandRequestHandler.h index cff6c10..5066c1d 100644 --- a/src/Daemon/RequestHandlers/CommandRequestHandler.h +++ b/src/Daemon/RequestHandlers/CommandRequestHandler.h @@ -21,12 +21,16 @@ #define MAD_DAEMON_REQUESTHANDLERS_COMMANDREQUESTHANDLER_H_ #include +#include namespace Mad { namespace Daemon { namespace RequestHandlers { class CommandRequestHandler : public Common::RequestHandler { + private: + void sendReply(Net::Connection *connection, uint16_t requestId); + protected: virtual void handlePacket(Net::Connection *connection, const Net::Packet &packet); -- cgit v1.2.3