Gaudi Framework, version v23r0

Home   Generated: Mon Jan 30 2012
Public Member Functions | Private Member Functions | Private Attributes

Gaudi::Utils::StopSignalHandler Class Reference

Service that stop the processing if a signal is received. More...

Inheritance diagram for Gaudi::Utils::StopSignalHandler:
Inheritance graph
[legend]
Collaboration diagram for Gaudi::Utils::StopSignalHandler:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 StopSignalHandler (const std::string &name, ISvcLocator *svcLoc)
StatusCode initialize ()
StatusCode finalize ()
virtual void handle (const Incident &)
 Inform that a new incident has occurred.

Private Member Functions

std::pair< int, bool > i_decodeSignal (const std::string &sig)
 Function to translate the signal name to the signal number.

Private Attributes

std::vector< std::stringm_usedSignals
 List of signal names or numbers (encoded as strings) to use to schedule a stop.
std::map< int, bool > m_signals
 Map of monitored signal numbers to the flag telling if they have to be propagated or not.
bool m_stopRequested
 Flag to remember if the stop has been requested because of a signal.
SmartIF< Gaudi::ISignalMonitor > m_signalMonitor
 Pointer to the signal monitor service.
SmartIF< IIncidentSvcm_incidentSvc
 Pointer to the incident service.
SmartIF< IPropertym_appProperty
 Pointer to the interface to set the return code of the application.

Detailed Description

Service that stop the processing if a signal is received.

The signals to be intercepted have to be declared in the property Signals as a list of strings (signal names or numbers). If '+' is appended to the signal name, then the signal is propagated to the signal handlers already registered when this service is initialized.

Definition at line 345 of file SignalMonitorSvc.cpp.


Constructor & Destructor Documentation

Gaudi::Utils::StopSignalHandler::StopSignalHandler ( const std::string name,
ISvcLocator svcLoc 
) [inline]

Definition at line 347 of file SignalMonitorSvc.cpp.

                                                                   : base_class(name, svcLoc) {
        m_usedSignals.reserve(2);
        m_usedSignals.push_back("SIGINT");
        m_usedSignals.push_back("SIGXCPU");
        declareProperty("Signals", m_usedSignals,
            "List of signal names or numbers to use to schedule a stop. "
            "If the signal is followed by a '+' the signal is propagated the previously "
            "registered handler (if any).");
      }

Member Function Documentation

StatusCode Gaudi::Utils::StopSignalHandler::finalize (  ) [inline, virtual]

Reimplemented from Service.

Definition at line 404 of file SignalMonitorSvc.cpp.

                            {
        m_incidentSvc->removeListener(this, IncidentType::BeginEvent);
        m_incidentSvc.reset();
        // disable the monitoring of the signals
        for (std::map<int, bool>::const_iterator s = m_signals.begin();
            s != m_signals.end(); ++s) {
          // tell the signal monitor that we are interested in these signals
          m_signalMonitor->ignoreSignal(s->first);
        }
        m_signalMonitor.reset();
        return Service::finalize();
      }
virtual void Gaudi::Utils::StopSignalHandler::handle ( const Incident  ) [inline, virtual]

Inform that a new incident has occurred.

Implements IIncidentListener.

Definition at line 417 of file SignalMonitorSvc.cpp.

                                           {
        if (!m_stopRequested) {
          const SigMap& sigmap(SigMap::instance());
          for (std::map<int, bool>::const_iterator s = m_signals.begin();
              s != m_signals.end(); ++s) {
            if (m_signalMonitor->gotSignal(s->first)) {
              warning() << "Received signal '" << sigmap.name(s->first)
                        << "' (" << s->first;
              const std::string &desc = sigmap.desc(s->first);
              if ( ! desc.empty() ) {
                warning() << ", " << desc;
              }
              warning() << ")" << endmsg;
              m_stopRequested = true;
              // Report the termination by signal at the end of the application
              using Gaudi::ReturnCode::SignalOffset;
              if (Gaudi::setAppReturnCode(m_appProperty, SignalOffset + s->first).isFailure()) {
                error() << "Could not set return code of the application ("
                    << SignalOffset + s->first << ")"
                    << endmsg;
              }
            }
          }
          if (m_stopRequested) {
            SmartIF<IEventProcessor> ep(serviceLocator());
            if (ep) {
              warning() << "Scheduling a stop" << endmsg;
              ep->stopRun().ignore();
            }
            else {
              warning() << "Cannot stop the processing because the IEventProcessor interface cannot be retrieved." << endmsg;
            }
          }
        }
      }
std::pair<int, bool> Gaudi::Utils::StopSignalHandler::i_decodeSignal ( const std::string sig ) [inline, private]

Function to translate the signal name to the signal number.

Definition at line 466 of file SignalMonitorSvc.cpp.

                                                              {
        debug() << "Decoding signal declaration '" << sig << "'" << endmsg;
        if ( sig.empty() || sig == "+" ) {
          debug() << "Empty signal, ignored" << endmsg;
          return std::make_pair<int, bool>(-1, false); // silently ignore empty strings
        }
        const SigMap& sigmap(SigMap::instance());
        std::string signal = sig;
        bool propagate = false;
        // Check if the signal must be propagated
        if (signal[signal.size() - 1] == '+') {
          debug() << "Must be propagated to previously registered signal handlers" << endmsg;
          propagate = true;
          signal.erase(signal.size() - 1, 1); // remove the '+' at the end of the string
        }
        int signum = -1;
        // check if the signal is a number
        if (std::isdigit(signal[0])){
          std::istringstream ss(signal);
          ss >> signum;
        } else {
          // try to find the signal name in the list of known signals
          signum = sigmap.signum(signal);
        }
        if (signum < 0) {
          warning() << "Cannot understand signal identifier '" << sig << "', ignored" << endmsg;
        } else {
          verbose() << "Matched signal '" << sigmap.name(signum)
                    << "' (" << signum;
          const std::string &desc = sigmap.desc(signum);
          if ( ! desc.empty() ) {
            verbose() << ", " << desc;
          }
          verbose() << ")" << endmsg;
        }
        return std::make_pair(signum, propagate);
      }
StatusCode Gaudi::Utils::StopSignalHandler::initialize (  ) [inline, virtual]

Reimplemented from Service.

Definition at line 356 of file SignalMonitorSvc.cpp.

                              {
        StatusCode sc = Service::initialize();
        if (sc.isFailure()) {
          return sc;
        }
        std::string serviceName("Gaudi::Utils::SignalMonitorSvc");
        m_signalMonitor = serviceLocator()->service(serviceName);
        if ( ! m_signalMonitor ) {
          error() << "Cannot retrieve " << serviceName << endmsg;
          return StatusCode::FAILURE;
        }
        serviceName = "IncidentSvc";
        m_incidentSvc = serviceLocator()->service(serviceName);
        if ( ! m_incidentSvc ) {
          error() << "Cannot retrieve " << serviceName << endmsg;
          return StatusCode::FAILURE;
        }
        // Get the IMainAppStatus interface of the ApplicationMgr
        m_appProperty = serviceLocator();
        if ( ! m_appProperty ) {
          warning() << "Cannot retrieve IProperty interface of ApplicationMgr, "
                       "the return code will not be changed" << endmsg;
        }
        // Decode the signal names
        std::pair<int, bool> sigid;
        for (std::vector<std::string>::const_iterator signame = m_usedSignals.begin();
            signame != m_usedSignals.end(); ++signame) {
          sigid = i_decodeSignal(*signame);
          if (sigid.first >= 0) {
            m_signals[sigid.first] = sigid.second;
          }
        }
        debug() << "Stopping on the signals:" << endmsg;
        const SigMap& sigmap(SigMap::instance());
        for (std::map<int, bool>::const_iterator s = m_signals.begin();
            s != m_signals.end(); ++s) {
          debug() << "\t" << sigmap.name(s->first) << ": "
                  << sigmap.desc(s->first) << " (" << s->first << ")";
          if (s->second) debug() << " propagated";
          debug() << endmsg;
          // tell the signal monitor that we are interested in these signals
          m_signalMonitor->monitorSignal(s->first, s->second);
        }
        m_stopRequested = false;
        debug() << "Register to the IncidentSvc" << endmsg;
        m_incidentSvc->addListener(this, IncidentType::BeginEvent);
        return StatusCode::SUCCESS;
      }

Member Data Documentation

SmartIF<IProperty> Gaudi::Utils::StopSignalHandler::m_appProperty [private]

Pointer to the interface to set the return code of the application.

Definition at line 464 of file SignalMonitorSvc.cpp.

SmartIF<IIncidentSvc> Gaudi::Utils::StopSignalHandler::m_incidentSvc [private]

Pointer to the incident service.

Definition at line 462 of file SignalMonitorSvc.cpp.

SmartIF<Gaudi::ISignalMonitor> Gaudi::Utils::StopSignalHandler::m_signalMonitor [private]

Pointer to the signal monitor service.

Definition at line 460 of file SignalMonitorSvc.cpp.

std::map<int, bool> Gaudi::Utils::StopSignalHandler::m_signals [private]

Map of monitored signal numbers to the flag telling if they have to be propagated or not.

Definition at line 456 of file SignalMonitorSvc.cpp.

bool Gaudi::Utils::StopSignalHandler::m_stopRequested [private]

Flag to remember if the stop has been requested because of a signal.

Definition at line 458 of file SignalMonitorSvc.cpp.

std::vector<std::string> Gaudi::Utils::StopSignalHandler::m_usedSignals [private]

List of signal names or numbers (encoded as strings) to use to schedule a stop.

Definition at line 454 of file SignalMonitorSvc.cpp.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Mon Jan 30 2012 13:53:33 for Gaudi Framework, version v23r0 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004