summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2013-12-20 21:30:44 +0000
committerrandomdan <randomdan@localhost>2013-12-20 21:30:44 +0000
commit09c41819d83be23387a7c6b1447e5c3ee493edce (patch)
tree7c2161642b645daae934979af411cb895c65694f
parentOptimize json objects and output (diff)
downloadproject2-09c41819d83be23387a7c6b1447e5c3ee493edce.tar.bz2
project2-09c41819d83be23387a7c6b1447e5c3ee493edce.tar.xz
project2-09c41819d83be23387a7c6b1447e5c3ee493edce.zip
Improved signal handler
Basic scheduler that fires periodic component handlers
-rw-r--r--project2/daemon/p2daemonAppEngine.cpp82
-rw-r--r--project2/daemon/p2daemonAppEngine.h20
-rw-r--r--project2/daemon/p2daemonMain.cpp1
3 files changed, 86 insertions, 17 deletions
diff --git a/project2/daemon/p2daemonAppEngine.cpp b/project2/daemon/p2daemonAppEngine.cpp
index 942ab9f..e5a1b3c 100644
--- a/project2/daemon/p2daemonAppEngine.cpp
+++ b/project2/daemon/p2daemonAppEngine.cpp
@@ -7,18 +7,23 @@
std::string DaemonAppEngine::daemonType;
Glib::ustring DaemonAppEngine::reqPlatform;
-DaemonPtr DaemonAppEngine::daemon;
+int DaemonAppEngine::periodicTimeout;
+DaemonAppEngine::SignalMap DaemonAppEngine::signalMap;
DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options")
("help", new OptionFlagSet(&ShowHelpComponent::showHelp),
"Print usage and exit")("h")
("daemon.type", Options::value(&daemonType), "The core daemon module to run")
("daemon.platform", Options::value(&reqPlatform), "Platform")
+("daemon.periodicTimeout", Options::value(&periodicTimeout, 60),
+ "Delay between occurrences of component periodic calls (default 60s)")
END_OPTIONS(DaemonAppEngine);
-DaemonAppEngine::DaemonAppEngine(int argc, char ** argv)
+DaemonAppEngine::DaemonAppEngine(int argc, char ** argv) :
+ main_loop(Glib::MainLoop::create())
{
daemon = DaemonLoader::createNew(daemonType, argc, argv);
+ Glib::signal_timeout().connect_seconds(sigc::mem_fun(this, &DaemonAppEngine::periodicCallback), periodicTimeout);
}
DaemonAppEngine::~DaemonAppEngine()
@@ -27,7 +32,7 @@ DaemonAppEngine::~DaemonAppEngine()
}
void
-DaemonAppEngine::shutdown(int)
+DaemonAppEngine::shutdown()
{
DefaultSignalHandler(SIGINT);
DefaultSignalHandler(SIGUSR1);
@@ -35,28 +40,56 @@ DaemonAppEngine::shutdown(int)
DefaultSignalHandler(SIGQUIT);
DefaultSignalHandler(SIGTERM);
- Logger()->message(LOG_INFO, "Shutting down daemon.");
+ Logger()->messagebf(LOG_DEBUG, "%s: Shutting down events.", __PRETTY_FUNCTION__);
+ main_loop->quit();
+ Logger()->messagebf(LOG_DEBUG, "%s: Waiting for events to terminate.", __PRETTY_FUNCTION__);
+ evThread->join();
+ delete evThread;
+ Logger()->messagebf(LOG_INFO, "%s: Shutting down daemon.", __PRETTY_FUNCTION__);
daemon->shutdown();
- Logger()->message(LOG_INFO, "Daemon shut down.");
+ Logger()->messagebf(LOG_INFO, "%s: Daemon shut down.", __PRETTY_FUNCTION__);
}
void
-DaemonAppEngine::process() const
+DaemonAppEngine::process()
{
IgnoreSignal(SIGINT);
IgnoreSignal(SIGUSR1);
IgnoreSignal(SIGUSR2);
- AddSignalHandler(SIGQUIT, &shutdown);
- AddSignalHandler(SIGTERM, &shutdown);
+ AddSignalHandler(SIGQUIT, boost::bind(&DaemonAppEngine::shutdown, this));
+ AddSignalHandler(SIGTERM, boost::bind(&DaemonAppEngine::shutdown, this));
- Logger()->message(LOG_INFO, "Starting daemon.");
+ Logger()->messagebf(LOG_DEBUG, "%s: Starting events.", __PRETTY_FUNCTION__);
+ evThread = new std::thread(&Glib::MainLoop::run, main_loop.operator->());
+ Logger()->messagebf(LOG_INFO, "%s: Starting daemon.", __PRETTY_FUNCTION__);
daemon->run();
- Logger()->message(LOG_INFO, "Daemon exitted.");
+ Logger()->messagebf(LOG_INFO, "%s: Daemon exitted.", __PRETTY_FUNCTION__);
+}
+
+void
+DaemonAppEngine::signalHandler(int signum)
+{
+ SignalMap::const_iterator shi = signalMap.find(signum);
+ if (shi != signalMap.end()) {
+ shi->second(signum);
+ }
+ else {
+ Logger()->messagebf(LOG_WARNING, "%s: Failed to find signal handler for sig %d", __PRETTY_FUNCTION__, signum);
+ }
+}
+
+bool
+DaemonAppEngine::periodicCallback()
+{
+ Logger()->messagebf(LOG_DEBUG, "%s: firing component periodics.", __PRETTY_FUNCTION__);
+ Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1));
+ return true;
}
void
DaemonAppEngine::IgnoreSignal(int signum)
{
+ signalMap.erase(signum);
if (signal(signum, SIG_IGN) == SIG_ERR) {
Logger()->messagef(LOG_WARNING, "%s: Failed to ignore signal %d", __PRETTY_FUNCTION__, signum);
}
@@ -65,16 +98,41 @@ DaemonAppEngine::IgnoreSignal(int signum)
void
DaemonAppEngine::DefaultSignalHandler(int signum)
{
+ signalMap.erase(signum);
if (signal(signum, SIG_DFL) == SIG_ERR) {
Logger()->messagef(LOG_WARNING, "%s: Failed to restore default signal %d handler", __PRETTY_FUNCTION__, signum);
}
}
void
-DaemonAppEngine::AddSignalHandler(int signum, sighandler_t handler)
+DaemonAppEngine::AddSignalHandler(int signum, const SignalFunc & handler)
{
- if (signal(signum, handler) == SIG_ERR) {
+ if (signal(signum, signalHandler) == SIG_ERR) {
Logger()->messagef(LOG_WARNING, "%s: Failed to add signal %d handler", __PRETTY_FUNCTION__, signum);
}
+ signalMap.insert({signum, handler});
}
+#ifndef NDEBUG
+class DummyDaemon : public Daemon {
+ public:
+ DummyDaemon(int, char * []) : stop(false) { }
+ void run() const
+ {
+ Logger()->messagef(LOG_INFO, "%s: Running", __PRETTY_FUNCTION__);
+ while (!stop) {
+ sleep(1);
+ }
+ Logger()->messagef(LOG_INFO, "%s: Exiting", __PRETTY_FUNCTION__);
+ }
+ void shutdown() const
+ {
+ Logger()->messagef(LOG_INFO, "%s: Setting stop flag", __PRETTY_FUNCTION__);
+ stop = true;
+ }
+ private:
+ mutable bool stop;
+};
+DECLARE_GENERIC_LOADER("dummydaemon", DaemonLoader, DummyDaemon);
+#endif
+
diff --git a/project2/daemon/p2daemonAppEngine.h b/project2/daemon/p2daemonAppEngine.h
index 42eddc7..0b16f70 100644
--- a/project2/daemon/p2daemonAppEngine.h
+++ b/project2/daemon/p2daemonAppEngine.h
@@ -4,27 +4,39 @@
#include <options.h>
#include <boost/optional.hpp>
#include "lib/daemon.h"
+#include <thread>
+#include <glibmm/main.h>
class DaemonAppEngine {
public:
DaemonAppEngine(int, char **);
~DaemonAppEngine();
- void process() const;
+ void process();
INITOPTIONS;
static Glib::ustring reqPlatform;
static std::string daemonType;
+ static int periodicTimeout;
protected:
+ typedef boost::function<void(int)> SignalFunc;
+ typedef std::map<int, const SignalFunc> SignalMap;
+
static void IgnoreSignal(int signum);
static void DefaultSignalHandler(int signum);
- static void AddSignalHandler(int signum, sighandler_t handler);
+ static void AddSignalHandler(int signum, const SignalFunc & handler);
+
+ static SignalMap signalMap;
+ static void signalHandler(int);
private:
- static void shutdown(int);
- static DaemonPtr daemon;
+ Glib::RefPtr<Glib::MainLoop> main_loop;
+ std::thread * evThread;
+ bool periodicCallback();
+ void shutdown();
+ DaemonPtr daemon;
};
#endif
diff --git a/project2/daemon/p2daemonMain.cpp b/project2/daemon/p2daemonMain.cpp
index 6dfb3ac..20c4eb7 100644
--- a/project2/daemon/p2daemonMain.cpp
+++ b/project2/daemon/p2daemonMain.cpp
@@ -20,7 +20,6 @@ main(int argc, char ** argv)
dae.process();
//Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1));
- //Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1));
Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1));
}