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: 63 69 91.3 %
Date: 2026-08-03 02:19:58 Functions: 12 13 92.3 %
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          48 : Signal::Signal(EventManager *evm,
      20             :     const SignalCallbackMap &sig_callback_map,
      21             :     const std::vector<SignalChildHandler> &sigchld_callbacks,
      22          48 :     bool always_handle_sigchild) :
      23          48 :     signal_(*(evm->io_service())),
      24          48 :     sig_callback_map_(sig_callback_map),
      25          48 :     sigchld_callbacks_(sigchld_callbacks),
      26          48 :     always_handle_sigchild_(always_handle_sigchild) {
      27          48 :     Initialize();
      28          48 : }
      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          50 : Signal::~Signal() {
      40          50 : }
      41             : 
      42         102 : boost::system::error_code Signal::AddSignal(int sig) {
      43         102 :     boost::system::error_code ec;
      44         102 :     signal_.add(sig, ec);
      45         102 :     if (ec) {
      46           0 :         std::string sigstr(strsignal(sig));
      47           0 :         LOG(ERROR, sigstr << " registration failed: " << ec);
      48           0 :     }
      49         102 :     return ec;
      50             : }
      51             : 
      52           6 : void Signal::RegisterHandler(int sig, SignalHandler handler) {
      53           6 :     SignalCallbackMap::iterator it = sig_callback_map_.find(sig);
      54           6 :     if (it == sig_callback_map_.end()) {
      55             :         // Add signal first
      56           6 :         AddSignal(sig);
      57           6 :         sig_callback_map_.insert(std::make_pair(sig,
      58          12 :             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           6 : }
      64             : 
      65          59 : void Signal::NotifySigChld(const boost::system::error_code &error, int sig,
      66             :                                 int pid, int status) {
      67          61 :     BOOST_FOREACH(const SignalChildHandler &sh, sigchld_callbacks_) {
      68           1 :         sh(error, sig, pid, status);
      69             :     }
      70          59 : }
      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         116 : int Signal::WaitPid(int pid, int *status, int options) {
      85         116 :     return ::waitpid(pid, status, options);
      86             : }
      87             : 
      88         105 : void Signal::HandleSig(const boost::system::error_code &error, int sig) {
      89         105 :     if (!error) {
      90         105 :         if (!HandleSigOsSpecific(error, sig)) {
      91          46 :             NotifySig(error, sig);
      92             :         }
      93         105 :         RegisterSigHandler();
      94             :     }
      95         105 : }
      96             : 
      97         155 : void Signal::RegisterSigHandler() {
      98         155 :     signal_.async_wait(boost::bind(&Signal::HandleSig, this, _1, _2));
      99         155 : }
     100             : 
     101          50 : void Signal::Initialize() {
     102          50 :     boost::system::error_code ec;
     103             : 
     104             :     // Add signals
     105         234 :     BOOST_FOREACH(int sig, sig_callback_map_ | boost::adaptors::map_keys) {
     106          92 :         ec = AddSignal(sig);
     107             :     }
     108             : 
     109          50 :     ec = InitializeSigChild();
     110             : 
     111          50 :     RegisterSigHandler();
     112          50 : }
     113             : 
     114          48 : void Signal::Terminate() {
     115          48 :     boost::system::error_code ec;
     116          48 :     signal_.cancel(ec);
     117          48 :     signal_.clear(ec);
     118          48 : }
     119             : 
     120             : }  // namespace process

Generated by: LCOV version 1.14