diff options
| -rw-r--r-- | project2/daemon/p2daemonAppEngine.cpp | 82 | ||||
| -rw-r--r-- | project2/daemon/p2daemonAppEngine.h | 20 | ||||
| -rw-r--r-- | project2/daemon/p2daemonMain.cpp | 1 | 
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));  }  | 
