LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/io - process_signal_common.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 61 69 88.4 %
Date: 2026-09-07 02:14:47 Functions: 11 13 84.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
       3             : //
       4             : 
       5             : #include <sys/wait.h>
       6             : 
       7             : #include <boost/bind/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             : using namespace boost::placeholders;
      16             : 
      17             : namespace process {
      18             : 
      19          46 : Signal::Signal(EventManager *evm,
      20             :     const SignalCallbackMap &sig_callback_map,
      21             :     const std::vector<SignalChildHandler> &sigchld_callbacks,
      22          46 :     bool always_handle_sigchild) :
      23          46 :     signal_(*(evm->io_service())),
      24          46 :     sig_callback_map_(sig_callback_map),
      25          46 :     sigchld_callbacks_(sigchld_callbacks),
      26          46 :     always_handle_sigchild_(always_handle_sigchild) {
      27          46 :     Initialize();
      28          46 : }
      29             : 
      30           2 : Signal::Signal(EventManager *evm,
      31           2 :     const SignalCallbackMap &sig_callback_map) :
      32           2 :     signal_(*(evm->io_service())),
      33           2 :     sig_callback_map_(sig_callback_map),
      34           2 :     sigchld_callbacks_(std::vector<SignalChildHandler>()),
      35           2 :     always_handle_sigchild_(false) {
      36           2 :     Initialize();
      37           2 : }
      38             : 
      39          48 : Signal::~Signal() {
      40          48 : }
      41             : 
      42          96 : boost::system::error_code Signal::AddSignal(int sig) {
      43          96 :     boost::system::error_code ec;
      44          96 :     signal_.add(sig, ec);
      45          96 :     if (ec) {
      46           0 :         std::string sigstr(strsignal(sig));
      47           0 :         LOG(ERROR, sigstr << " registration failed: " << ec);
      48           0 :     }
      49          96 :     return ec;
      50             : }
      51             : 
      52           2 : void Signal::RegisterHandler(int sig, SignalHandler handler) {
      53           2 :     SignalCallbackMap::iterator it = sig_callback_map_.find(sig);
      54           2 :     if (it == sig_callback_map_.end()) {
      55             :         // Add signal first
      56           2 :         AddSignal(sig);
      57           2 :         sig_callback_map_.insert(std::make_pair(sig,
      58           4 :             std::vector<SignalHandler>(1, handler)));
      59             :     } else {
      60           0 :         std::vector<SignalHandler> &sig_handlers(it->second);
      61           0 :         sig_handlers.push_back(handler);
      62             :     }
      63           2 : }
      64             : 
      65           1 : void Signal::NotifySigChld(const boost::system::error_code &error, int sig,
      66             :                                 int pid, int status) {
      67           3 :     BOOST_FOREACH(const SignalChildHandler &sh, sigchld_callbacks_) {
      68           1 :         sh(error, sig, pid, status);
      69             :     }
      70           1 : }
      71             : 
      72          46 : void Signal::NotifySig(const boost::system::error_code &error,
      73             :                               int sig) {
      74          46 :     SignalCallbackMap::const_iterator it = sig_callback_map_.find(sig);
      75          46 :     if (it == sig_callback_map_.end()) {
      76           0 :         return;
      77             :     }
      78          46 :     const std::vector<SignalHandler> &callbacks(it->second);
      79         138 :     BOOST_FOREACH(const SignalHandler &sh, callbacks) {
      80          46 :         sh(error, sig);
      81             :     }
      82             : }
      83             : 
      84           0 : int Signal::WaitPid(int pid, int *status, int options) {
      85           0 :     return ::waitpid(pid, status, options);
      86             : }
      87             : 
      88          47 : void Signal::HandleSig(const boost::system::error_code &error, int sig) {
      89          47 :     if (!error) {
      90          47 :         if (!HandleSigOsSpecific(error, sig)) {
      91          46 :             NotifySig(error, sig);
      92             :         }
      93          47 :         RegisterSigHandler();
      94             :     }
      95          47 : }
      96             : 
      97          95 : void Signal::RegisterSigHandler() {
      98          95 :     signal_.async_wait(boost::bind(&Signal::HandleSig, this, _1, _2));
      99          95 : }
     100             : 
     101          48 : void Signal::Initialize() {
     102          48 :     boost::system::error_code ec;
     103             : 
     104             :     // Add signals
     105         232 :     BOOST_FOREACH(int sig, sig_callback_map_ | boost::adaptors::map_keys) {
     106          92 :         ec = AddSignal(sig);
     107             :     }
     108             : 
     109          48 :     ec = InitializeSigChild();
     110             : 
     111          48 :     RegisterSigHandler();
     112          48 : }
     113             : 
     114          46 : void Signal::Terminate() {
     115          46 :     boost::system::error_code ec;
     116          46 :     signal_.cancel(ec);
     117          46 :     signal_.clear(ec);
     118          46 : }
     119             : 
     120             : }  // namespace process

Generated by: LCOV version 1.14