34 typedef struct sigaction handler_t;
46 oldact = signal( signum, sa );
49 sigemptyset( &sa.sa_mask );
51 sigaction( signum, &sa, &oldact );
92 for (
int i = 0; i < NSIG; ++i ) {
126 m_caught[signum] = 1;
129 m_oldActions[signum] != SIG_DFL
131 m_oldActions[signum].sa_handler != SIG_DFL
135 m_oldActions[signum]( signum );
137 m_oldActions[signum].sa_handler( signum );
179 const char* sig_desc(
int signum )
181 if ( signum >= NSIG || signum < 0 )
return nullptr;
187 return "Illegal instruction";
189 return "Floating point exception";
191 return "Segmentation fault";
195 return "Trace/breakpoint trap";
202 return sys_siglist[signum];
217 inline const std::string&
name(
int signum )
const {
return m_num2id[signum]; }
219 inline const std::string& desc(
int signum )
const {
return m_num2desc[signum]; }
223 auto it = m_name2num.
find( str );
224 return it != m_name2num.end() ? it->second : -1;
232 #define addSignal( id ) i_addSignal( id, #id ); 321 inline void i_addSignal(
int signum,
const char* signame )
323 m_num2id[signum] = signame;
324 m_name2num[signame] = signum;
325 const char* desc = sig_desc( signum );
327 m_num2desc[signum] = desc;
328 m_name2num[desc] = signum;
353 using extends::extends;
360 std::string serviceName(
"Gaudi::Utils::SignalMonitorSvc" );
362 if ( !m_signalMonitor ) {
363 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
366 serviceName =
"IncidentSvc";
368 if ( !m_incidentSvc ) {
369 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
374 if ( !m_appProperty ) {
375 warning() <<
"Cannot retrieve IProperty interface of ApplicationMgr, " 376 "the return code will not be changed" 380 for (
const auto& signame : m_usedSignals ) {
381 auto sigid = i_decodeSignal( signame );
382 if ( sigid.first >= 0 ) {
383 m_signals[sigid.first] = sigid.second;
387 const SigMap& sigmap( SigMap::instance() );
388 for (
const auto&
s : m_signals ) {
389 debug() <<
"\t" << sigmap.name(
s.first ) <<
": " << sigmap.desc(
s.first ) <<
" (" <<
s.first <<
")";
390 if (
s.second )
debug() <<
" propagated";
393 m_signalMonitor->monitorSignal(
s.first,
s.second );
395 m_stopRequested =
false;
396 debug() <<
"Register to the IncidentSvc" <<
endmsg;
397 m_incidentSvc->addListener(
this, IncidentType::BeginEvent );
402 m_incidentSvc->removeListener(
this, IncidentType::BeginEvent );
403 m_incidentSvc.reset();
407 m_signalMonitor->ignoreSignal( s.first );
409 m_signalMonitor.reset();
415 if ( !m_stopRequested ) {
416 const SigMap& sigmap( SigMap::instance() );
417 for (
const auto&
s : m_signals ) {
418 if ( !m_signalMonitor->gotSignal(
s.first ) )
continue;
419 warning() <<
"Received signal '" << sigmap.name(
s.first ) <<
"' (" <<
s.first;
423 m_stopRequested =
true;
430 if ( m_stopRequested ) {
434 ep->stopRun().ignore();
436 warning() <<
"Cannot stop the processing because the IEventProcessor interface cannot be retrieved." 448 {
"SIGINT",
"SIGXCPU"},
449 "List of signal names or numbers to use to schedule a stop. " 450 "If the signal is followed by a '+' the signal is propagated the previously " 451 "registered handler (if any)."};
455 bool m_stopRequested =
false;
465 debug() <<
"Decoding signal declaration '" << sig <<
"'" <<
endmsg;
466 if ( sig.
empty() || sig ==
"+" ) {
470 const SigMap& sigmap( SigMap::instance() );
474 if ( signal[signal.
size() - 1] ==
'+' ) {
475 debug() <<
"Must be propagated to previously registered signal handlers" <<
endmsg;
486 signum = sigmap.signum( signal );
489 warning() <<
"Cannot understand signal identifier '" << sig <<
"', ignored" <<
endmsg;
491 verbose() <<
"Matched signal '" << sigmap.name( signum ) <<
"' (" << signum;
493 if ( !desc.
empty() ) {
498 return {signum, propagate};
void setSignal(int signum) override
Set the flag for the given signal, as if the signal was received.
constexpr static const auto FAILURE
StatusCode initialize() override
sig_atomic_t m_caught[NSIG]
Array of flags for received signals.
Small smart pointer class with automatic reference counting for IInterface.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
const std::string & name() const override
Retrieve name of the service.
StatusCode finalize() override
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
Implementation of property with value of concrete type.
Gaudi::Utils::SignalMonitorSvc g_u_sms
~SignalMonitorSvc() override
Stop monitoring signals and clear the instance pointer.
bool gotSignal(int signum) const override
Check if the given signal has been received.
void i_handle(int signum)
void ignoreSignal(int signum) override
Remove the specific signal handler for the requested signal, restoring the previous signal handler...
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
static void dispatcher(int signum)
Signal handler function.
class MergingTransformer< Out(const vector_of_const_< In > void
void clearSignal(int signum) override
Clear the flag for the given signal, so that a new occurrence can be identified.
StatusCode finalize() override
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
Pointer to the signal monitor service.
#define DECLARE_COMPONENT(type)
MonitoringMode
Possible monitoring modes.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
std::map< int, bool > m_signals
Map of monitored signal numbers to the flag telling if they have to be propagated or not...
static void setInstance(SignalMonitorSvc *i)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
static SignalMonitorSvc * instance()
Method to get the singleton instance.
Implementation of Gaudi::ISignalMonitor.
This class is used for returning status codes from appropriate routines.
SignalMonitorSvc(const std::string &name, ISvcLocator *svcLoc)
Initialize internal variables of the service and set the instance pointer.
void handle(const Incident &) override
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.
Service that stop the processing if a signal is received.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
constexpr static const auto SUCCESS
static SignalMonitorSvc * s_instance
Pointer to the current instance.
void monitorSignal(int signum, bool propagate) override
Declare a signal to be monitored.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Base class used to extend a class implementing other interfaces.
Base class for all Incidents (computing events).
StatusCode initialize() override
The IEventProcessor is the interface to process events.
MonitoringMode m_monitored[NSIG]
Array of flags to keep track of monitored signals.
constexpr int SignalOffset
handler_t m_oldActions[NSIG]
List of replaced signal actions (for the recovery when disable the monitoring).
handler_t m_defaultAction
Helper variable for default signal action.
Gaudi::Utils::StopSignalHandler g_u_ssh
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Helper functions to set/get the application return code.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
struct sigaction handler_t