Gaudi::Utils::StopSignalHandler Class Reference

Service that stop the processing if a signal is received. More...

Inheritance diagram for Gaudi::Utils::StopSignalHandler:
Collaboration diagram for Gaudi::Utils::StopSignalHandler:

Public Member Functions

 StopSignalHandler (const std::string &name, ISvcLocator *svcLoc)
 
StatusCode initialize () override
 
StatusCode finalize () override
 
void handle (const Incident &) override
 
- Public Member Functions inherited from extends< BASE, Interfaces >
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
 ~extends () override=default
 Virtual destructor. More...
 
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
 ~extends () override=default
 Virtual destructor. More...
 
- Public Member Functions inherited from extend_interfaces< Interfaces...>
 ~extend_interfaces () override=default
 Virtual destructor. More...
 
 ~extend_interfaces () override=default
 Virtual destructor. More...
 

Private Member Functions

std::pair< int, bool > i_decodeSignal (const std::string &sig)
 Function to translate the signal name to the signal number. More...
 

Private Attributes

std::vector< std::string > m_usedSignals
 List of signal names or numbers (encoded as strings) to use to schedule a stop. More...
 
std::map< int, bool > m_signals
 Map of monitored signal numbers to the flag telling if they have to be propagated or not. More...
 
bool m_stopRequested
 Flag to remember if the stop has been requested because of a signal. More...
 
SmartIF< Gaudi::ISignalMonitorm_signalMonitor
 Pointer to the signal monitor service. More...
 
SmartIF< IIncidentSvcm_incidentSvc
 Pointer to the incident service. More...
 
SmartIF< IPropertym_appProperty
 Pointer to the interface to set the return code of the application. More...
 

Additional Inherited Members

- Public Types inherited from extends< BASE, Interfaces >
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces...>
 Typedef to the base of this class. More...
 
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces...>
 Typedef to the base of this class. More...
 
- Public Types inherited from extend_interfaces< Interfaces...>
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids...>::type
 take union of the ext_iids of all Interfaces... More...
 
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids...>::type
 take union of the ext_iids of all Interfaces... More...
 

Detailed Description

Service that stop the processing if a signal is received.

The signals to be intercepted have to be declared in the property Signals as a list of strings (signal names or numbers). If '+' is appended to the signal name, then the signal is propagated to the signal handlers already registered when this service is initialized.

Definition at line 339 of file SignalMonitorSvc.cpp.

Constructor & Destructor Documentation

Gaudi::Utils::StopSignalHandler::StopSignalHandler ( const std::string &  name,
ISvcLocator svcLoc 
)
inline

Definition at line 341 of file SignalMonitorSvc.cpp.

341  : base_class(name, svcLoc) {
342  m_usedSignals.reserve(2);
343  m_usedSignals.push_back("SIGINT");
344  m_usedSignals.push_back("SIGXCPU");
345  m_stopRequested = false;
346  declareProperty("Signals", m_usedSignals,
347  "List of signal names or numbers to use to schedule a stop. "
348  "If the signal is followed by a '+' the signal is propagated the previously "
349  "registered handler (if any).");
350  }
bool m_stopRequested
Flag to remember if the stop has been requested because of a signal.
extends base_class
Typedef to this class.
Definition: extends.h:14
std::vector< std::string > m_usedSignals
List of signal names or numbers (encoded as strings) to use to schedule a stop.

Member Function Documentation

StatusCode Gaudi::Utils::StopSignalHandler::finalize ( )
inlineoverride

Definition at line 396 of file SignalMonitorSvc.cpp.

396  {
397  m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
399  // disable the monitoring of the signals
400  std::for_each( std::begin(m_signals), std::end(m_signals),
401  [&](const std::pair<int,bool>& s) {
402  // tell the signal monitor that we are interested in these signals
403  m_signalMonitor->ignoreSignal(s.first);
404  } );
405  m_signalMonitor.reset();
406  return Service::finalize();
407  }
StatusCode finalize() override
Definition: Service.cpp:188
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
Pointer to the signal monitor service.
std::map< int, bool > m_signals
Map of monitored signal numbers to the flag telling if they have to be propagated or not...
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
string s
Definition: gaudirun.py:245
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:88
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
void Gaudi::Utils::StopSignalHandler::handle ( const Incident )
inlineoverride

Definition at line 409 of file SignalMonitorSvc.cpp.

409  {
410  if (!m_stopRequested) {
411  const SigMap& sigmap(SigMap::instance());
412  for (const auto& s : m_signals ) {
413  if (!m_signalMonitor->gotSignal(s.first)) continue;
414  warning() << "Received signal '" << sigmap.name(s.first)
415  << "' (" << s.first;
416  const std::string &desc = sigmap.desc(s.first);
417  if ( ! desc.empty() ) warning() << ", " << desc;
418  warning() << ")" << endmsg;
419  m_stopRequested = true;
420  // Report the termination by signal at the end of the application
423  error() << "Could not set return code of the application ("
424  << SignalOffset + s.first << ")"
425  << endmsg;
426  }
427 
428  }
429  if (m_stopRequested) {
430  auto ep = serviceLocator()->as<IEventProcessor>();
431  if (ep) {
432  warning() << "Scheduling a stop" << endmsg;
433  ep->stopRun().ignore();
434  }
435  else {
436  warning() << "Cannot stop the processing because the IEventProcessor interface cannot be retrieved." << endmsg;
437  }
438  }
439  }
440  }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool m_stopRequested
Flag to remember if the stop has been requested because of a signal.
int maxevt auto ep
Definition: Bootstrap.cpp:285
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
Pointer to the signal monitor service.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
std::map< int, bool > m_signals
Map of monitored signal numbers to the flag telling if they have to be propagated or not...
SmartIF< IProperty > m_appProperty
Pointer to the interface to set the return code of the application.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:50
string s
Definition: gaudirun.py:245
The IEventProcessor is the interface to process events.
constexpr int SignalOffset
Definition: AppReturnCode.h:34
std::pair<int, bool> Gaudi::Utils::StopSignalHandler::i_decodeSignal ( const std::string &  sig)
inlineprivate

Function to translate the signal name to the signal number.

Definition at line 455 of file SignalMonitorSvc.cpp.

455  {
456  debug() << "Decoding signal declaration '" << sig << "'" << endmsg;
457  if ( sig.empty() || sig == "+" ) {
458  debug() << "Empty signal, ignored" << endmsg;
459  return {-1, false}; // silently ignore empty strings
460  }
461  const SigMap& sigmap(SigMap::instance());
462  std::string signal = sig;
463  bool propagate = false;
464  // Check if the signal must be propagated
465  if (signal[signal.size() - 1] == '+') {
466  debug() << "Must be propagated to previously registered signal handlers" << endmsg;
467  propagate = true;
468  signal.erase(signal.size() - 1, 1); // remove the '+' at the end of the string
469  }
470  int signum = -1;
471  // check if the signal is a number
472  if (std::isdigit(signal[0])){
473  std::istringstream ss(signal);
474  ss >> signum;
475  } else {
476  // try to find the signal name in the list of known signals
477  signum = sigmap.signum(signal);
478  }
479  if (signum < 0) {
480  warning() << "Cannot understand signal identifier '" << sig << "', ignored" << endmsg;
481  } else {
482  verbose() << "Matched signal '" << sigmap.name(signum)
483  << "' (" << signum;
484  const std::string &desc = sigmap.desc(signum);
485  if ( ! desc.empty() ) {
486  verbose() << ", " << desc;
487  }
488  verbose() << ")" << endmsg;
489  }
490  return {signum, propagate};
491  }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode Gaudi::Utils::StopSignalHandler::initialize ( )
inlineoverride

Definition at line 351 of file SignalMonitorSvc.cpp.

351  {
353  if (sc.isFailure()) {
354  return sc;
355  }
356  std::string serviceName("Gaudi::Utils::SignalMonitorSvc");
357  m_signalMonitor = serviceLocator()->service(serviceName);
358  if ( ! m_signalMonitor ) {
359  error() << "Cannot retrieve " << serviceName << endmsg;
360  return StatusCode::FAILURE;
361  }
362  serviceName = "IncidentSvc";
363  m_incidentSvc = serviceLocator()->service(serviceName);
364  if ( ! m_incidentSvc ) {
365  error() << "Cannot retrieve " << serviceName << endmsg;
366  return StatusCode::FAILURE;
367  }
368  // Get the IMainAppStatus interface of the ApplicationMgr
369  m_appProperty = serviceLocator();
370  if ( ! m_appProperty ) {
371  warning() << "Cannot retrieve IProperty interface of ApplicationMgr, "
372  "the return code will not be changed" << endmsg;
373  }
374  // Decode the signal names
375  for (const auto& signame : m_usedSignals ) {
376  auto sigid = i_decodeSignal(signame);
377  if (sigid.first >= 0) {
378  m_signals[sigid.first] = sigid.second;
379  }
380  }
381  debug() << "Stopping on the signals:" << endmsg;
382  const SigMap& sigmap(SigMap::instance());
383  for (const auto& s : m_signals ) {
384  debug() << "\t" << sigmap.name(s.first) << ": "
385  << sigmap.desc(s.first) << " (" << s.first << ")";
386  if (s.second) debug() << " propagated";
387  debug() << endmsg;
388  // tell the signal monitor that we are interested in these signals
389  m_signalMonitor->monitorSignal(s.first, s.second);
390  }
391  m_stopRequested = false;
392  debug() << "Register to the IncidentSvc" << endmsg;
393  m_incidentSvc->addListener(this, IncidentType::BeginEvent);
394  return StatusCode::SUCCESS;
395  }
StatusCode initialize() override
Definition: Service.cpp:63
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool m_stopRequested
Flag to remember if the stop has been requested because of a signal.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
Pointer to the signal monitor service.
std::vector< std::string > m_usedSignals
List of signal names or numbers (encoded as strings) to use to schedule a stop.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
std::map< int, bool > m_signals
Map of monitored signal numbers to the flag telling if they have to be propagated or not...
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
SmartIF< IProperty > m_appProperty
Pointer to the interface to set the return code of the application.
std::pair< int, bool > i_decodeSignal(const std::string &sig)
Function to translate the signal name to the signal number.
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
string s
Definition: gaudirun.py:245

Member Data Documentation

SmartIF<IProperty> Gaudi::Utils::StopSignalHandler::m_appProperty
private

Pointer to the interface to set the return code of the application.

Definition at line 453 of file SignalMonitorSvc.cpp.

SmartIF<IIncidentSvc> Gaudi::Utils::StopSignalHandler::m_incidentSvc
private

Pointer to the incident service.

Definition at line 451 of file SignalMonitorSvc.cpp.

SmartIF<Gaudi::ISignalMonitor> Gaudi::Utils::StopSignalHandler::m_signalMonitor
private

Pointer to the signal monitor service.

Definition at line 449 of file SignalMonitorSvc.cpp.

std::map<int, bool> Gaudi::Utils::StopSignalHandler::m_signals
private

Map of monitored signal numbers to the flag telling if they have to be propagated or not.

Definition at line 445 of file SignalMonitorSvc.cpp.

bool Gaudi::Utils::StopSignalHandler::m_stopRequested
private

Flag to remember if the stop has been requested because of a signal.

Definition at line 447 of file SignalMonitorSvc.cpp.

std::vector<std::string> Gaudi::Utils::StopSignalHandler::m_usedSignals
private

List of signal names or numbers (encoded as strings) to use to schedule a stop.

Definition at line 443 of file SignalMonitorSvc.cpp.


The documentation for this class was generated from the following file: