31 typedef struct sigaction handler_t;
42 oldact = signal(signum, sa);
45 sigemptyset(&sa.sa_mask);
47 sigaction(signum, &sa, &oldact);
93 for(
int i = 0;
i < NSIG; ++
i){
104 for (
int i = 0;
i < NSIG; ++
i) {
182 const char *sig_desc(
int signum) {
183 if (signum >= NSIG || signum < 0)
187 case SIGINT:
return "Interrupt";
188 case SIGILL:
return "Illegal instruction";
189 case SIGFPE:
return "Floating point exception";
190 case SIGSEGV:
return "Segmentation fault";
191 case SIGTERM:
return "Terminated";
192 case SIGBREAK:
return "Trace/breakpoint trap";
193 case SIGABRT:
return "Aborted";
197 return sys_siglist[signum];
205 static const SigMap& instance() {
210 inline const std::string &name(
int signum)
const {
211 return m_num2id[signum];
214 inline const std::string &desc(
int signum)
const {
215 return m_num2desc[signum];
218 inline int signum(
const std::string &str)
const {
220 it = m_name2num.
find(str);
221 if (it == m_name2num.
end()) {
230 #define addSignal(id) i_addSignal(id, #id);
319 inline void i_addSignal(
int signum,
const char *signame) {
320 m_num2id[signum] = signame;
321 m_name2num[signame] = signum;
322 const char* desc = sig_desc(signum);
324 m_num2desc[signum] = desc;
325 m_name2num[desc] = signum;
353 "List of signal names or numbers to use to schedule a stop. "
354 "If the signal is followed by a '+' the signal is propagated the previously "
355 "registered handler (if any).");
362 std::string serviceName(
"Gaudi::Utils::SignalMonitorSvc");
365 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
368 serviceName =
"IncidentSvc";
371 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
377 warning() <<
"Cannot retrieve IProperty interface of ApplicationMgr, "
378 "the return code will not be changed" <<
endmsg;
381 std::pair<int, bool> sigid;
382 for (std::vector<std::string>::const_iterator signame =
m_usedSignals.begin();
385 if (sigid.first >= 0) {
390 const SigMap& sigmap(SigMap::instance());
391 for (std::map<int, bool>::const_iterator
s =
m_signals.begin();
393 debug() <<
"\t" << sigmap.name(
s->first) <<
": "
394 << sigmap.desc(
s->first) <<
" (" <<
s->first <<
")";
395 if (
s->second)
debug() <<
" propagated";
401 debug() <<
"Register to the IncidentSvc" <<
endmsg;
409 for (std::map<int, bool>::const_iterator
s =
m_signals.begin();
420 const SigMap& sigmap(SigMap::instance());
421 for (std::map<int, bool>::const_iterator
s =
m_signals.begin();
424 warning() <<
"Received signal '" << sigmap.name(
s->first)
425 <<
"' (" <<
s->first;
426 const std::string &desc = sigmap.desc(
s->first);
427 if ( ! desc.empty() ) {
435 error() <<
"Could not set return code of the application ("
445 ep->stopRun().ignore();
448 warning() <<
"Cannot stop the processing because the IEventProcessor interface cannot be retrieved." <<
endmsg;
468 debug() <<
"Decoding signal declaration '" << sig <<
"'" <<
endmsg;
469 if ( sig.empty() || sig ==
"+" ) {
471 return std::make_pair<int, bool>(-1,
false);
473 const SigMap& sigmap(SigMap::instance());
474 std::string signal = sig;
475 bool propagate =
false;
477 if (signal[signal.size() - 1] ==
'+') {
478 debug() <<
"Must be propagated to previously registered signal handlers" <<
endmsg;
480 signal.erase(signal.size() - 1, 1);
484 if (std::isdigit(signal[0])){
485 std::istringstream ss(signal);
489 signum = sigmap.signum(signal);
492 warning() <<
"Cannot understand signal identifier '" << sig <<
"', ignored" <<
endmsg;
494 verbose() <<
"Matched signal '" << sigmap.name(signum)
496 const std::string &desc = sigmap.desc(signum);
497 if ( ! desc.empty() ) {
502 return std::make_pair(signum, propagate);
const std::string BeginEvent
Processing of a new event has started.
sig_atomic_t m_caught[NSIG]
Array of flags for received signals.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
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.
bool gotSignal(int signum) const
Check if the given signal has been received.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
void clearSignal(int signum)
Clear the flag for the given signal, so that a new occurrence can be identified.
Gaudi::Utils::SignalMonitorSvc g_u_sms
void i_handle(int signum)
void ignoreSignal(int signum)
Remove the specific signal handler for the requested signal, restoring the previous signal handler...
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
static void dispatcher(int signum)
Signal handler function.
StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
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.
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)
static SignalMonitorSvc * instance()
Method to get the singleton instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Implementation of Gaudi::ISignalMonitor.
virtual void handle(const Incident &)
Inform that a new incident has occurred.
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.
Base class used to extend a class implementing other interfaces.
iterator find(const key_type &key)
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.
void setSignal(int signum)
Set the flag for the given signal, as if the signal was received.
map_type::const_iterator const_iterator
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.
virtual const std::string & name() const
Retrieve name of the service.
static SignalMonitorSvc * s_instance
Pointer to the current instance.
void monitorSignal(int signum, bool propagate)
Declare a signal to be monitored.
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Base class for all Incidents (computing events).
Templated class to add the standard messaging functionalities.
StopSignalHandler(const std::string &name, ISvcLocator *svcLoc)
MonitoringMode m_monitored[NSIG]
Array of flags to keep track of monitored signals.
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.
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
This is a number of static methods for bootstrapping the Gaudi framework.
virtual ~SignalMonitorSvc()
Stop monitoring signals and clear the instance pointer.
StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Gaudi::Utils::StopSignalHandler g_u_ssh
void reset(TYPE *ptr=0)
Set the internal pointer to the passed one disposing of the old one.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
struct sigaction handler_t
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.