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

Generated by: LCOV version 1.14