39 typedef void( __cdecl*
handler_t )( int );
52 oldact = signal( signum, sa );
55 sigemptyset( &sa.sa_mask );
57 sigaction( signum, &sa, &oldact );
96 for (
int i = 0; i < NSIG; ++i ) {
183 const char* sig_desc(
int signum ) {
184 if ( signum >= NSIG || signum < 0 )
return nullptr;
190 return "Illegal instruction";
192 return "Floating point exception";
194 return "Segmentation fault";
198 return "Trace/breakpoint trap";
205 return sys_siglist[signum];
213 static const SigMap& instance() {
218 inline const std::string&
name(
int signum )
const {
return m_num2id[signum]; }
220 inline const std::string& desc(
int signum )
const {
return m_num2desc[signum]; }
222 inline int signum(
const std::string& str )
const {
223 auto it = m_name2num.
find( str );
224 return it != m_name2num.end() ? it->second : -1;
231 #define addSignal( id ) i_addSignal( id, #id ); 320 inline void i_addSignal(
int signum,
const char* signame ) {
321 m_num2id[signum] = signame;
322 m_name2num[signame] = signum;
323 const char* desc = sig_desc( signum );
325 m_num2desc[signum] = desc;
326 m_name2num[desc] = signum;
348 using extends::extends;
352 std::string serviceName(
"Gaudi::Utils::SignalMonitorSvc" );
355 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
358 serviceName =
"IncidentSvc";
361 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
367 warning() <<
"Cannot retrieve IProperty interface of ApplicationMgr, " 368 "the return code will not be changed" 374 if ( sigid.first >= 0 ) {
m_signals[sigid.first] = sigid.second; }
377 const SigMap& sigmap( SigMap::instance() );
379 debug() <<
"\t" << sigmap.name(
s.first ) <<
": " << sigmap.desc(
s.first ) <<
" (" <<
s.first <<
")";
380 if (
s.second )
debug() <<
" propagated";
386 debug() <<
"Register to the IncidentSvc" <<
endmsg;
404 const SigMap& sigmap( SigMap::instance() );
407 warning() <<
"Received signal '" << sigmap.name(
s.first ) <<
"' (" <<
s.first;
422 ep->stopRun().ignore();
424 warning() <<
"Cannot stop the processing because the IEventProcessor interface cannot be retrieved." 436 {
"SIGINT",
"SIGXCPU"},
437 "List of signal names or numbers to use to schedule a stop. " 438 "If the signal is followed by a '+' the signal is propagated the previously " 439 "registered handler (if any)."};
452 debug() <<
"Decoding signal declaration '" << sig <<
"'" <<
endmsg;
453 if ( sig.
empty() || sig ==
"+" ) {
457 const SigMap& sigmap( SigMap::instance() );
459 bool propagate =
false;
461 if ( signal[signal.size() - 1] ==
'+' ) {
462 debug() <<
"Must be propagated to previously registered signal handlers" <<
endmsg;
464 signal.erase( signal.size() - 1, 1 );
473 signum = sigmap.signum( signal );
476 warning() <<
"Cannot understand signal identifier '" << sig <<
"', ignored" <<
endmsg;
478 verbose() <<
"Matched signal '" << sigmap.name( signum ) <<
"' (" << signum;
483 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.
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.
Implementation of property with value of concrete type.
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
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.
constexpr static const auto SUCCESS
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.
#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)
virtual bool gotSignal(int signum) const =0
Tell if the given signal has been received or not.
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.
virtual void ignoreSignal(int signum)=0
Ignore future occurrences of the given signal number.
void handle(const Incident &) override
Gaudi::Property< std::vector< std::string > > m_usedSignals
List of signal names or numbers (encoded as strings) to use to schedule a stop.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
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.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
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.
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
constexpr static const auto FAILURE
The IEventProcessor is the interface to process events.
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.
Gaudi::Utils::StopSignalHandler g_u_ssh
virtual void monitorSignal(int signum, bool propagate=true)=0
Add a signal (number) to the list of signals to be monitored.
Header file for std:chrono::duration-based Counters.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
struct sigaction handler_t