|
Gaudi Framework, version v22r4 |
| Home | Generated: Fri Sep 2 2011 |
Default implementation of the IIncidentSvc interface. More...
#include <IncidentSvc.h>


Classes | |
| struct | Listener |
Public Types | |
| typedef std::list< Listener > | ListenerList |
| typedef GaudiUtils::HashMap < Gaudi::StringKey, ListenerList * > | ListenerMap |
Public Member Functions | |
| virtual StatusCode | initialize () |
| virtual StatusCode | finalize () |
| virtual void | addListener (IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false) |
| Add listener. | |
| virtual void | removeListener (IIncidentListener *lis, const std::string &type="") |
| Remove listener. | |
| virtual void | fireIncident (const Incident &incident) |
| Fire an Incident. | |
| IncidentSvc (const std::string &name, ISvcLocator *svc) | |
| virtual | ~IncidentSvc () |
Private Member Functions | |
| void | i_fireIncident (const Incident &incident, const std::string &type) |
| Internal function to allow incidents listening to all events. | |
Private Attributes | |
| ListenerMap | m_listenerMap |
| List of auditor names. | |
| const std::string * | m_currentIncidentType |
| Incident being fired. | |
| boost::recursive_mutex | m_listenerMapMutex |
| Mutex to synchronize access to m_listenerMap. | |
| ChronoEntity | m_timer |
| timer & it's lock | |
| bool | m_timerLock |
Default implementation of the IIncidentSvc interface.
This implementation is thread-safe with the following features:
Definition at line 37 of file IncidentSvc.h.
| typedef std::list<Listener> IncidentSvc::ListenerList |
Definition at line 55 of file IncidentSvc.h.
| typedef GaudiUtils::HashMap<Gaudi::StringKey, ListenerList*> IncidentSvc::ListenerMap |
Definition at line 57 of file IncidentSvc.h.
| IncidentSvc::IncidentSvc | ( | const std::string & | name, |
| ISvcLocator * | svc | ||
| ) |
Definition at line 51 of file IncidentSvc.cpp.
: base_class(name, svc) , m_currentIncidentType(0) , m_timer() , m_timerLock ( false ) {}
| IncidentSvc::~IncidentSvc | ( | ) | [virtual] |
Definition at line 58 of file IncidentSvc.cpp.
{
boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
for (ListenerMap::iterator i = m_listenerMap.begin();
i != m_listenerMap.end();
++i) {
delete i->second;
}
}
| void IncidentSvc::addListener | ( | IIncidentListener * | lis, |
| const std::string & | type = "", |
||
| long | priority = 0, |
||
| bool | rethrow = false, |
||
| bool | singleShot = false |
||
| ) | [virtual] |
Add listener.
Implements IIncidentSvc.
Definition at line 107 of file IncidentSvc.cpp.
{
boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
std::string ltype;
if( type == "" ) ltype = "ALL";
else ltype = type;
// find if the type already exists
ListenerMap::iterator itMap = m_listenerMap.find( ltype );
if( itMap == m_listenerMap.end() ) {
// if not found, create and insert now a list of listeners
ListenerList* newlist = new ListenerList();
std::pair<ListenerMap::iterator, bool> p;
p = m_listenerMap.insert(ListenerMap::value_type(ltype, newlist));
if( p.second ) itMap = p.first;
}
ListenerList* llist = (*itMap).second;
// add Listener in the ListenerList according to the priority
ListenerList::iterator itlist;
for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) {
if( (*itlist).priority < prio ) {
// We insert before the current position
break;
}
}
DEBMSG << "Adding [" << type << "] listener '" << getListenerName(lis)
<< "' with priority " << prio << endmsg;
llist->insert(itlist, Listener(lis, prio, rethrow, singleShot));
}
| StatusCode IncidentSvc::finalize | ( | void | ) | [virtual] |
Reimplemented from Service.
Definition at line 92 of file IncidentSvc.cpp.
{
DEBMSG << m_timer.outputUserTime( "Incident timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
<< m_timer.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
// Finalize this specific service
StatusCode sc = Service::finalize();
if ( UNLIKELY(sc.isFailure()) ) { return sc; }
return StatusCode::SUCCESS;
}
| void IncidentSvc::fireIncident | ( | const Incident & | incident ) | [virtual] |
Fire an Incident.
| Incident | being fired |
Implements IIncidentSvc.
Definition at line 280 of file IncidentSvc.cpp.
{
Gaudi::Utils::LockedChrono timer ( m_timer , m_timerLock ) ;
// Call specific listeners
i_fireIncident(incident, incident.type());
// Try listeners registered for ALL incidents
if ( incident.type() != "ALL" ){ // avoid double calls if somebody fires the incident "ALL"
i_fireIncident(incident, "ALL");
}
}
| void IncidentSvc::i_fireIncident | ( | const Incident & | incident, |
| const std::string & | type | ||
| ) | [private] |
Internal function to allow incidents listening to all events.
Definition at line 212 of file IncidentSvc.cpp.
{
boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
// Special case: FailInputFile incident must set the application return code
if (incident.type() == IncidentType::FailInputFile) {
// Set the return code to Gaudi::ReturnCode::FailInput (2)
SmartIF<IProperty> appmgr(serviceLocator());
Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::FailInput).ignore();
}
ListenerMap::iterator itmap = m_listenerMap.find( listenerType );
if ( m_listenerMap.end() == itmap ) return;
// setting this pointer will avoid that a call to removeListener() during
// the loop triggers a segfault
m_currentIncidentType = &(incident.type());
ListenerList* llist = (*itmap).second;
ListenerList::iterator itlist;
bool weHaveToCleanUp = false;
// loop over all registered Listeners
for( itlist = llist->begin(); itlist != llist->end(); itlist++ )
{
VERMSG << "Calling '" << getListenerName((*itlist).iListener)
<< "' for incident [" << incident.type() << "]" << endmsg;
// handle exceptions if they occur
try {
(*itlist).iListener->handle(incident);
}
catch( const GaudiException& exc ) {
error() << "Exception with tag=" << exc.tag() << " is caught"
" handling incident" << m_currentIncidentType << endmsg;
error() << exc << endmsg;
if ( (*itlist).rethrow ) { throw (exc); }
}
catch( const std::exception& exc ) {
error() << "Standard std::exception is caught"
" handling incident" << m_currentIncidentType << endmsg;
error() << exc.what() << endmsg;
if ( (*itlist).rethrow ) { throw (exc); }
}
catch(...) {
error() << "UNKNOWN Exception is caught"
" handling incident" << m_currentIncidentType << endmsg;
if ( (*itlist).rethrow ) { throw; }
}
// check if at least one of the listeners is a one-shot
weHaveToCleanUp |= itlist->singleShot;
}
if (weHaveToCleanUp) {
// remove all the listeners that need to be removed from the list
llist->remove_if( listenerToBeRemoved() );
// if the list is empty, we can remove it
if( llist->size() == 0) {
delete llist;
m_listenerMap.erase(itmap);
}
}
m_currentIncidentType = 0;
}
| StatusCode IncidentSvc::initialize | ( | void | ) | [virtual] |
Reimplemented from Service.
Definition at line 71 of file IncidentSvc.cpp.
{
// initialize the Service Base class
StatusCode sc = Service::initialize();
if ( sc.isFailure() ) {
return sc;
}
m_currentIncidentType = 0;
// set my own (IncidentSvc) properties via the jobOptionService
sc = setProperties();
if ( UNLIKELY(sc.isFailure()) )
{
error() << "Could not set my properties" << endmsg;
return sc;
}
return StatusCode::SUCCESS;
}
| void IncidentSvc::removeListener | ( | IIncidentListener * | lis, |
| const std::string & | type = "" |
||
| ) | [virtual] |
Remove listener.
Implements IIncidentSvc.
Definition at line 143 of file IncidentSvc.cpp.
{
boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
if( type == "") {
// remove Listener from all the lists
ListenerMap::iterator itmap;
for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();)
{
// since the current entry may be eventually deleted
// we need to keep a memory of the next index before
// calling recursively this method
ListenerMap::iterator itmap_old = itmap;
itmap++;
removeListener( lis, (*itmap_old).first );
}
}
else {
ListenerMap::iterator itmap = m_listenerMap.find( type );
if( itmap == m_listenerMap.end() ) {
// if not found the incident type then return
return;
}
else {
ListenerList* llist = (*itmap).second;
ListenerList::iterator itlist;
bool justScheduleForRemoval = ( 0!= m_currentIncidentType )
&& (type == *m_currentIncidentType);
// loop over all the entries in the Listener list
// to remove all of them than matches
// the listener address. Remember the next index
// before erasing the current one
for( itlist = llist->begin(); itlist != llist->end(); ) {
if( (*itlist).iListener == lis || lis == 0) {
if (justScheduleForRemoval) {
(itlist++)->singleShot = true; // remove it as soon as it is safe
}
else {
DEBMSG << "Removing [" << type << "] listener '"
<< getListenerName(lis) << "'" << endmsg;
itlist = llist->erase(itlist); // remove from the list now
}
}
else {
itlist++;
}
}
if( llist->size() == 0) {
delete llist;
m_listenerMap.erase(itmap);
}
}
}
}
const std::string* IncidentSvc::m_currentIncidentType [private] |
Incident being fired.
It is used to know if we can safely remove a listener or we have to schedule its removal for later.
Definition at line 94 of file IncidentSvc.h.
ListenerMap IncidentSvc::m_listenerMap [private] |
List of auditor names.
Definition at line 90 of file IncidentSvc.h.
boost::recursive_mutex IncidentSvc::m_listenerMapMutex [private] |
Mutex to synchronize access to m_listenerMap.
Definition at line 97 of file IncidentSvc.h.
ChronoEntity IncidentSvc::m_timer [mutable, private] |
timer & it's lock
Definition at line 100 of file IncidentSvc.h.
bool IncidentSvc::m_timerLock [mutable, private] |
Definition at line 101 of file IncidentSvc.h.