OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
process_signal_common.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3 //
4 
5 #include <sys/wait.h>
6 
7 #include <boost/bind.hpp>
8 #include <boost/foreach.hpp>
9 #include <boost/range/adaptor/map.hpp>
10 
11 #include <base/logging.h>
12 #include <io/event_manager.h>
13 #include <io/process_signal.h>
14 
15 namespace process {
16 
18  const SignalCallbackMap &sig_callback_map,
19  const std::vector<SignalChildHandler> &sigchld_callbacks,
20  bool always_handle_sigchild) :
21  signal_(*(evm->io_service())),
22  sig_callback_map_(sig_callback_map),
23  sigchld_callbacks_(sigchld_callbacks),
24  always_handle_sigchild_(always_handle_sigchild) {
25  Initialize();
26 }
27 
29  const SignalCallbackMap &sig_callback_map) :
30  signal_(*(evm->io_service())),
31  sig_callback_map_(sig_callback_map),
32  sigchld_callbacks_(std::vector<SignalChildHandler>()),
33  always_handle_sigchild_(false) {
34  Initialize();
35 }
36 
38 }
39 
40 boost::system::error_code Signal::AddSignal(int sig) {
41  boost::system::error_code ec;
42  signal_.add(sig, ec);
43  if (ec) {
44  std::string sigstr(strsignal(sig));
45  LOG(ERROR, sigstr << " registration failed: " << ec);
46  }
47  return ec;
48 }
49 
50 void Signal::RegisterHandler(int sig, SignalHandler handler) {
51  SignalCallbackMap::iterator it = sig_callback_map_.find(sig);
52  if (it == sig_callback_map_.end()) {
53  // Add signal first
54  AddSignal(sig);
55  sig_callback_map_.insert(std::make_pair(sig,
56  std::vector<SignalHandler>(1, handler)));
57  } else {
58  std::vector<SignalHandler> &sig_handlers(it->second);
59  sig_handlers.push_back(handler);
60  }
61 }
62 
63 void Signal::NotifySigChld(const boost::system::error_code &error, int sig,
64  int pid, int status) {
65  BOOST_FOREACH(const SignalChildHandler &sh, sigchld_callbacks_) {
66  sh(error, sig, pid, status);
67  }
68 }
69 
70 void Signal::NotifySig(const boost::system::error_code &error,
71  int sig) {
72  SignalCallbackMap::const_iterator it = sig_callback_map_.find(sig);
73  if (it == sig_callback_map_.end()) {
74  return;
75  }
76  const std::vector<SignalHandler> &callbacks(it->second);
77  BOOST_FOREACH(const SignalHandler &sh, callbacks) {
78  sh(error, sig);
79  }
80 }
81 
82 int Signal::WaitPid(int pid, int *status, int options) {
83  return ::waitpid(pid, status, options);
84 }
85 
86 void Signal::HandleSig(const boost::system::error_code &error, int sig) {
87  if (!error) {
88  if (!HandleSigOsSpecific(error, sig)) {
89  NotifySig(error, sig);
90  }
92  }
93 }
94 
96  signal_.async_wait(boost::bind(&Signal::HandleSig, this, _1, _2));
97 }
98 
100  boost::system::error_code ec;
101 
102  // Add signals
103  BOOST_FOREACH(int sig, sig_callback_map_ | boost::adaptors::map_keys) {
104  ec = AddSignal(sig);
105  }
106 
107  ec = InitializeSigChild();
108 
110 }
111 
113  boost::system::error_code ec;
114  signal_.cancel(ec);
115  signal_.clear(ec);
116 }
117 
118 } // namespace process
void HandleSig(const boost::system::error_code &error, int sig)
void RegisterHandler(int sig, SignalHandler handler)
boost::system::error_code AddSignal(int sig)
std::vector< SignalChildHandler > sigchld_callbacks_
static Options options
void NotifySig(const boost::system::error_code &error, int sig)
std::map< int, std::vector< SignalHandler > > SignalCallbackMap
boost::function< void(const boost::system::error_code &error, int sig)> SignalHandler
virtual int WaitPid(int pid, int *status, int options)
SignalCallbackMap sig_callback_map_
boost::asio::signal_set signal_
void NotifySigChld(const boost::system::error_code &error, int sig, int pid, int status)
#define LOG(_Level, _Msg)
Definition: logging.h:33
boost::system::error_code InitializeSigChild()
boost::function< void(const boost::system::error_code &error, int sig, pid_t pid, int status)> SignalChildHandler
bool HandleSigOsSpecific(const boost::system::error_code &error, int sig)
static EventManager evm
Signal(EventManager *evm, const SignalCallbackMap &sig_callback_map, const std::vector< SignalChildHandler > &sigchld_callbacks, bool always_handle_sigchild)