27 Gaudi::ISignalMonitor> {
32 typedef struct sigaction handler_t;
43 oldact = signal(signum, sa);
46 sigemptyset(&sa.sa_mask);
48 sigaction(signum, &sa, &oldact);
94 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);
181 const char *sig_desc(
int signum) {
182 if (signum >= NSIG || signum < 0)
186 case SIGINT:
return "Interrupt";
187 case SIGILL:
return "Illegal instruction";
188 case SIGFPE:
return "Floating point exception";
189 case SIGSEGV:
return "Segmentation fault";
190 case SIGTERM:
return "Terminated";
191 case SIGBREAK:
return "Trace/breakpoint trap";
192 case SIGABRT:
return "Aborted";
196 return sys_siglist[signum];
204 static const SigMap& instance() {
210 return m_num2id[signum];
214 return m_num2desc[signum];
218 auto it = m_name2num.
find(str);
219 return it != m_name2num.end() ? it->second : -1;
225 #define addSignal(id) i_addSignal(id, #id);
314 inline void i_addSignal(
int signum,
const char *signame) {
315 m_num2id[signum] = signame;
316 m_name2num[signame] = signum;
317 const char* desc = sig_desc(signum);
319 m_num2desc[signum] = desc;
320 m_name2num[desc] = signum;
349 "List of signal names or numbers to use to schedule a stop. "
350 "If the signal is followed by a '+' the signal is propagated the previously "
351 "registered handler (if any).");
358 std::string serviceName(
"Gaudi::Utils::SignalMonitorSvc");
361 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
364 serviceName =
"IncidentSvc";
367 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
373 warning() <<
"Cannot retrieve IProperty interface of ApplicationMgr, "
374 "the return code will not be changed" <<
endmsg;
379 if (sigid.first >= 0) {
384 const SigMap& sigmap(SigMap::instance());
386 debug() <<
"\t" << sigmap.name(
s.first) <<
": "
387 << sigmap.desc(
s.first) <<
" (" <<
s.first <<
")";
388 if (
s.second)
debug() <<
" propagated";
394 debug() <<
"Register to the IncidentSvc" <<
endmsg;
413 const SigMap& sigmap(SigMap::instance());
416 warning() <<
"Received signal '" << sigmap.name(
s.first)
425 error() <<
"Could not set return code of the application ("
435 ep->stopRun().ignore();
438 warning() <<
"Cannot stop the processing because the IEventProcessor interface cannot be retrieved." <<
endmsg;
458 debug() <<
"Decoding signal declaration '" << sig <<
"'" <<
endmsg;
459 if ( sig.
empty() || sig ==
"+" ) {
463 const SigMap& sigmap(SigMap::instance());
465 bool propagate =
false;
467 if (signal[signal.
size() - 1] ==
'+') {
468 debug() <<
"Must be propagated to previously registered signal handlers" <<
endmsg;
479 signum = sigmap.signum(signal);
482 warning() <<
"Cannot understand signal identifier '" << sig <<
"', ignored" <<
endmsg;
484 verbose() <<
"Matched signal '" << sigmap.name(signum)
487 if ( ! desc.
empty() ) {
492 return {signum, propagate};
void setSignal(int signum) override
Set the flag for the given signal, as if the signal was received.
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.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
bool m_stopRequested
Flag to remember if the stop has been requested because of a signal.
StatusCode finalize() override
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
Gaudi::Utils::SignalMonitorSvc g_u_sms
~SignalMonitorSvc() override
Stop monitoring signals and clear the instance pointer.
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.
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.
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.
#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...
const std::string & name() const override
Retrieve name of the service.
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.
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.
bool gotSignal(int signum) const override
Check if the given signal has been received.
Base class for all Incidents (computing events).
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
StatusCode initialize() override
The IEventProcessor is the interface to process events.
StopSignalHandler(const std::string &name, ISvcLocator *svcLoc)
MonitoringMode m_monitored[NSIG]
Array of flags to keep track of monitored signals.
constexpr int SignalOffset
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
handler_t m_oldActions[NSIG]
List of replaced signal actions (for the recovery when disable the monitoring).
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
handler_t m_defaultAction
Helper variable for default signal action.
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Gaudi::Utils::StopSignalHandler g_u_ssh
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