47 sigemptyset( &sa.sa_mask );
49 sigaction( signum, &sa, &oldact );
79 for (
int i = 0; i < NSIG; ++i ) {
151 const char* sig_desc(
int signum ) {
152 if ( signum >= NSIG || signum < 0 )
return nullptr;
153 return strsignal( signum );
160 static const SigMap& instance() {
165 inline const std::string&
name(
int signum )
const {
return m_num2id[signum]; }
167 inline const std::string& desc(
int signum )
const {
return m_num2desc[signum]; }
169 inline int signum(
const std::string& str )
const {
170 auto it = m_name2num.find( str );
171 return it != m_name2num.end() ? it->second : -1;
178#define addSignal( id ) i_addSignal( id, #id );
267 inline void i_addSignal(
int signum,
const char* signame ) {
268 m_num2id[signum] = signame;
269 m_name2num[signame] = signum;
270 const char* desc = sig_desc( signum );
272 m_num2desc[signum] = desc;
273 m_name2num[desc] = signum;
276 GaudiUtils::HashMap<std::string, int> m_name2num;
277 GaudiUtils::HashMap<int, std::string> m_num2id;
278 GaudiUtils::HashMap<int, std::string> m_num2desc;
295 using extends::extends;
299 std::string serviceName(
"Gaudi::Utils::SignalMonitorSvc" );
302 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
305 serviceName =
"IncidentSvc";
308 error() <<
"Cannot retrieve " << serviceName <<
endmsg;
314 warning() <<
"Cannot retrieve IProperty interface of ApplicationMgr, "
315 "the return code will not be changed"
321 if ( sigid.first >= 0 ) {
m_signals[sigid.first] = sigid.second; }
324 const SigMap& sigmap( SigMap::instance() );
326 debug() <<
"\t" << sigmap.name( s.first ) <<
": " << sigmap.desc( s.first ) <<
" (" << s.first <<
")";
327 if ( s.second )
debug() <<
" propagated";
333 debug() <<
"Register to the IncidentSvc" <<
endmsg;
334 m_incidentSvc->addListener(
this, IncidentType::BeginEvent );
338 m_incidentSvc->removeListener(
this, IncidentType::BeginEvent );
341 std::for_each( std::begin(
m_signals ), std::end(
m_signals ), [&](
const std::pair<int, bool>& s ) {
351 const SigMap& sigmap( SigMap::instance() );
354 warning() <<
"Received signal '" << sigmap.name( s.first ) <<
"' (" << s.first;
355 const std::string& desc = sigmap.desc( s.first );
356 if ( !desc.empty() )
warning() <<
", " << desc;
362 error() <<
"Could not set return code of the application (" << SignalOffset + s.first <<
")" <<
endmsg;
369 ep->stopRun().ignore();
371 warning() <<
"Cannot stop the processing because the IEventProcessor interface cannot be retrieved."
383 {
"SIGINT",
"SIGXCPU" },
384 "List of signal names or numbers to use to schedule a stop. "
385 "If the signal is followed by a '+' the signal is propagated the previously "
386 "registered handler (if any)." };
399 debug() <<
"Decoding signal declaration '" << sig <<
"'" <<
endmsg;
400 if ( sig.empty() || sig ==
"+" ) {
402 return { -1,
false };
404 const SigMap& sigmap( SigMap::instance() );
405 std::string signal = sig;
406 bool propagate =
false;
408 if ( signal[signal.size() - 1] ==
'+' ) {
409 debug() <<
"Must be propagated to previously registered signal handlers" <<
endmsg;
411 signal.erase( signal.size() - 1, 1 );
415 if ( std::isdigit( signal[0] ) ) {
416 std::istringstream ss( signal );
420 signum = sigmap.signum( signal );
423 warning() <<
"Cannot understand signal identifier '" << sig <<
"', ignored" <<
endmsg;
425 verbose() <<
"Matched signal '" << sigmap.name( signum ) <<
"' (" << signum;
426 const std::string& desc = sigmap.desc( signum );
427 if ( !desc.empty() ) {
verbose() <<
", " << desc; }
430 return { signum, propagate };
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
Gaudi::Utils::SignalMonitorSvc g_u_sms
Gaudi::Utils::StopSignalHandler g_u_ssh
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Implementation of property with value of concrete type.
Implementation of Gaudi::ISignalMonitor.
void ignoreSignal(int signum) override
Remove the specific signal handler for the requested signal, restoring the previous signal handler.
void clearSignal(int signum) override
Clear the flag for the given signal, so that a new occurrence can be identified.
handler_t m_defaultAction
Helper variable for default signal action.
SignalMonitorSvc(const std::string &name, ISvcLocator *svcLoc)
Initialize internal variables of the service and set the instance pointer.
static void dispatcher(int signum)
Signal handler function.
sig_atomic_t m_caught[NSIG]
Array of flags for received signals.
void i_handle(int signum)
struct sigaction handler_t
bool gotSignal(int signum) const override
Check if the given signal has been received.
~SignalMonitorSvc() override
Stop monitoring signals and clear the instance pointer.
static void setInstance(SignalMonitorSvc *i)
void setSignal(int signum) override
Set the flag for the given signal, as if the signal was received.
MonitoringMode
Possible monitoring modes.
static SignalMonitorSvc * instance()
Method to get the singleton instance.
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).
void monitorSignal(int signum, bool propagate) override
Declare a signal to be monitored.
static SignalMonitorSvc * s_instance
Pointer to the current instance.
Service that stop the processing if a signal is received.
bool m_stopRequested
Flag to remember if the stop has been requested because of a signal.
Gaudi::Property< std::vector< std::string > > m_usedSignals
List of signal names or numbers (encoded as strings) to use to schedule a stop.
std::pair< int, bool > i_decodeSignal(const std::string &sig)
Function to translate the signal name to the signal number.
SmartIF< IIncidentSvc > m_incidentSvc
Pointer to the incident service.
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
Pointer to the signal monitor service.
StatusCode initialize() override
std::map< int, bool > m_signals
Map of monitored signal numbers to the flag telling if they have to be propagated or not.
StatusCode finalize() override
void handle(const Incident &) override
SmartIF< IProperty > m_appProperty
Pointer to the interface to set the return code of the application.
The IEventProcessor is the interface to process events.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Base class for all Incidents (computing events).
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
StatusCode finalize() override
const std::string & name() const override
Retrieve name of the service.
StatusCode initialize() override
Small smart pointer class with automatic reference counting for IInterface.
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
Base class used to extend a class implementing other interfaces.
constexpr int SignalOffset
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.