libmoost
|
00001 /* vim:set ts=3 sw=3 sts=3 et: */ 00028 #ifndef MOOST_UTILS_HUP_HANDLER_HPP__ 00029 #define MOOST_UTILS_HUP_HANDLER_HPP__ 00030 00031 #include <csignal> 00032 #include <cstdlib> 00033 00034 #include <boost/function.hpp> 00035 00036 namespace moost { namespace process { 00037 00051 00052 class hup_handler 00053 { 00054 private: 00055 // A Meyers Singleton (http://bit.ly/EsS4p) 00056 static hup_handler & get_single_instance() 00057 { 00058 static hup_handler hup_handler; 00059 return hup_handler; 00060 } 00061 00062 public: 00063 typedef boost::function<void ()> handler_t; 00064 00065 // Set the customer handler. 00066 static void set(handler_t const & handler) 00067 { 00068 hup_handler & hup_handler = hup_handler::get_single_instance(); 00069 hup_handler.handler_ = handler; 00070 hup_handler.register_handler(); 00071 } 00072 00073 private: 00074 handler_t handler_; 00075 00076 // This is the proxy handler, which calls the custom handler 00077 static void sighandler(int) 00078 { 00079 hup_handler & hup_handler = hup_handler::get_single_instance(); 00080 00081 if(hup_handler.handler_) 00082 { 00083 hup_handler.handler_(); 00084 } 00085 } 00086 00087 // Register the proxy handler 00088 struct sigaction sa_; 00089 void register_handler() 00090 { 00091 memset(&sa_, 0, sizeof(sa_)); 00092 sa_.sa_handler = hup_handler::sighandler; 00093 00094 // These are the signals we'll block whilst the handlers being called 00095 sigemptyset(&sa_.sa_mask); 00096 sa_.sa_flags = SIG_BLOCK; 00097 sigaddset(&sa_.sa_mask, SIGHUP); 00098 00099 // These are the signals we'll trap and handle 00100 sigaction(SIGHUP, &sa_, NULL); 00101 } 00102 }; 00103 00104 }} 00105 00106 #endif // MOOST_UTILS_HUP_HANDLER_HPP__