Gaudi Framework, version v20r2

Generated: 18 Jul 2008

IncidentSvc Class Reference

#include <IncidentSvc.h>

Inheritance diagram for IncidentSvc:

Inheritance graph
[legend]
Collaboration diagram for IncidentSvc:

Collaboration graph
[legend]
List of all members.

Detailed Description

Definition at line 23 of file IncidentSvc.h.

Public Types

typedef std::list< ListenerListenerList
typedef std::map< std::string,
ListenerList * > 
ListenerMap

Public Member Functions

virtual StatusCode initialize ()
 Initialization (from CONFIGURED to INITIALIZED).
virtual StatusCode finalize ()
 Finalize (from INITIALIZED to CONFIGURED).
virtual StatusCode queryInterface (const InterfaceID &riid, void **ppvInterface)
 Query interfaces of Interface.
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 Attributes

ListenerMap m_listenerMap
const std::stringm_currentIncidentType
 Incident being fired.

Classes

struct  Listener


Member Typedef Documentation

typedef std::list<Listener> IncidentSvc::ListenerList

Definition at line 40 of file IncidentSvc.h.

typedef std::map<std::string, ListenerList*> IncidentSvc::ListenerMap

Definition at line 41 of file IncidentSvc.h.


Constructor & Destructor Documentation

IncidentSvc::IncidentSvc ( const std::string name,
ISvcLocator svc 
)

Definition at line 29 of file IncidentSvc.cpp.

00030 : Service(name, svc),m_currentIncidentType(0) {
00031 }

IncidentSvc::~IncidentSvc (  )  [virtual]

Definition at line 33 of file IncidentSvc.cpp.

References m_listenerMap.

00033                           { 
00034   for (ListenerMap::iterator i = m_listenerMap.begin();
00035        i != m_listenerMap.end();
00036        ++i) {
00037     delete i->second;
00038   }
00039 }


Member Function Documentation

StatusCode IncidentSvc::initialize (  )  [virtual]

Initialization (from CONFIGURED to INITIALIZED).

Reimplemented from Service.

Definition at line 45 of file IncidentSvc.cpp.

References endreq(), MSG::ERROR, Service::initialize(), StatusCode::isFailure(), Service::msgSvc(), Service::name(), Service::setProperties(), and StatusCode::SUCCESS.

00045                                    {
00046   // initialize the Service Base class
00047   StatusCode sc = Service::initialize();
00048   if ( sc.isFailure() ) {
00049     return sc;
00050   }
00051 
00052   MsgStream log( msgSvc(), name() ); 
00053 
00054   // set my own (IncidentSvc) properties via the jobOptionService 
00055   sc = setProperties();
00056   if ( sc.isFailure() ) {
00057     log << MSG::ERROR << "Could not set my properties" << endreq;
00058     return sc;
00059   }
00060 
00061   return StatusCode::SUCCESS;
00062 }

StatusCode IncidentSvc::finalize (  )  [virtual]

Finalize (from INITIALIZED to CONFIGURED).

Reimplemented from Service.

Definition at line 64 of file IncidentSvc.cpp.

References Service::finalize(), StatusCode::isFailure(), and StatusCode::SUCCESS.

00064                                  {
00065   // Finalize this specific service
00066   StatusCode sc = Service::finalize();
00067   if ( sc.isFailure() ) {
00068     return sc;
00069   }
00070 
00071   return StatusCode::SUCCESS;
00072 }

StatusCode IncidentSvc::queryInterface ( const InterfaceID riid,
void **  ppvInterface 
) [virtual]

Query interfaces of Interface.

Parameters:
riid ID of Interface to be retrieved
ppvUnknown Pointer to Location for interface pointer

Reimplemented from Service.

Definition at line 74 of file IncidentSvc.cpp.

References Service::addRef(), IID_IIncidentSvc, Service::queryInterface(), and StatusCode::SUCCESS.

00074                                                                                      {
00075   if ( IID_IIncidentSvc == riid )    {
00076     *ppvInterface = (IIncidentSvc*)this;
00077   }
00078   else  {
00079     // Interface is not directly available: try out a base class
00080     return Service::queryInterface(riid, ppvInterface);
00081   }
00082   addRef();
00083   return StatusCode::SUCCESS;
00084 }

void IncidentSvc::addListener ( IIncidentListener lis,
const std::string type = "",
long  priority = 0,
bool  rethrow = false,
bool  singleShot = false 
) [virtual]

Add listener.

Parameters:
lis Listener address
type Incident type
priority Priority in handling incident

Implements IIncidentSvc.

Definition at line 90 of file IncidentSvc.cpp.

References std::list< _Tp, _Alloc >::begin(), MSG::DEBUG, std::list< _Tp, _Alloc >::end(), endreq(), std::pair< _T1, _T2 >::first, getListenerName(), std::list< _Tp, _Alloc >::insert(), m_listenerMap, Service::msgSvc(), Service::name(), std::pair< _T1, _T2 >::second, and Service::type().

00091                                                                                           {
00092 
00093   std::string ltype;
00094   if( type == "" ) ltype = "ALL";
00095   else             ltype = type;
00096   // find if the type already exists
00097   ListenerMap::iterator itMap = m_listenerMap.find( ltype );
00098   if( itMap == m_listenerMap.end() ) {
00099     // if not found, create and insert now a list of listeners
00100     ListenerList* newlist = new ListenerList();
00101     std::pair<ListenerMap::iterator, bool> p;
00102     p = m_listenerMap.insert(ListenerMap::value_type(ltype, newlist));
00103     if( p.second ) itMap = p.first;
00104   }
00105   ListenerList* llist = (*itMap).second;
00106   // add Listener in the ListenerList according to the priority
00107   ListenerList::iterator itlist;
00108   for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) {
00109     if( (*itlist).priority < prio ) {
00110       // We insert before the current position
00111       break;
00112     }
00113   }
00114 
00115   MsgStream log ( msgSvc() , name());
00116   log << MSG::DEBUG << "Adding [" << type << "] listener '" << getListenerName(lis)
00117       << "' with priority " << prio << endreq;
00118   
00119   llist->insert(itlist, Listener(lis, prio, rethrow, singleShot));
00120   return;
00121 }

void IncidentSvc::removeListener ( IIncidentListener lis,
const std::string type = "" 
) [virtual]

Remove listener.

Parameters:
lis Listener address
type Incident type

Implements IIncidentSvc.

Definition at line 123 of file IncidentSvc.cpp.

References std::list< _Tp, _Alloc >::begin(), MSG::DEBUG, std::list< _Tp, _Alloc >::end(), endreq(), std::list< _Tp, _Alloc >::erase(), getListenerName(), m_currentIncidentType, m_listenerMap, Service::msgSvc(), Service::name(), std::list< _Tp, _Alloc >::size(), and Service::type().

00123                                                                               {
00124 
00125   MsgStream log ( msgSvc() , name());
00126   if( type == "") {
00127     // remove Listener from all the lists
00128     ListenerMap::iterator itmap;
00129     for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();) {
00130       // since the current entry may be eventually deleted 
00131       // we need to keep a memory of the next index before calling recursivelly this method
00132       ListenerMap::iterator itmap_old = itmap;
00133       itmap++;
00134       removeListener( lis, (*itmap_old).first );
00135     }
00136   }
00137   else {
00138     ListenerMap::iterator itmap = m_listenerMap.find( type );
00139     if( itmap == m_listenerMap.end() ) {
00140       // if not found the incident type then return
00141       return;
00142     }
00143     else {
00144       ListenerList* llist = (*itmap).second;
00145       ListenerList::iterator itlist;
00146       bool justScheduleForRemoval = ( 0!= m_currentIncidentType )
00147                                     && (type == *m_currentIncidentType);
00148       // loop over all the entries in the Listener list to remove all of them than matches 
00149       // the listener address. Remember the next index before erasing the current one
00150       for( itlist = llist->begin(); itlist != llist->end(); ) {
00151         if( (*itlist).iListener == lis || lis == 0) {
00152           if (justScheduleForRemoval) {
00153             (itlist++)->singleShot = true; // remove it as soon as it is safe
00154           }
00155           else {
00156             log << MSG::DEBUG << "Removing [" << type << "] listener '"
00157                 << getListenerName(lis) << "'" << endreq;
00158             itlist = llist->erase(itlist); // remove from the list now
00159           }
00160         }
00161         else {
00162           itlist++;
00163         }
00164       }
00165       if( llist->size() == 0) {
00166         delete llist;
00167         m_listenerMap.erase(itmap);
00168       }
00169     }
00170   }
00171   return;
00172 }

void IncidentSvc::fireIncident ( const Incident incident  )  [virtual]

Fire an Incident.

Parameters:
Incident being fired

Implements IIncidentSvc.

Definition at line 184 of file IncidentSvc.cpp.

References endreq(), MSG::ERROR, getListenerName(), m_currentIncidentType, m_listenerMap, Service::msgSvc(), Service::name(), GaudiException::tag(), Incident::type(), MSG::VERBOSE, and std::exception::what().

00184                                                          {
00185         // setting this pointer will avoid that a call to removeListener() during
00186         // the loop triggers a segfault
00187   m_currentIncidentType = &(incident.type());
00188   
00189   MsgStream log ( msgSvc() , name());
00190   ListenerMap::iterator itmap = m_listenerMap.find( incident.type() );
00191   if( itmap != m_listenerMap.end() ) {
00192     ListenerList* llist = (*itmap).second;
00193     ListenerList::iterator itlist;
00194     bool weHaveToCleanUp = false;
00195     // loop over all registered Listeners
00196     for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) {
00197       log << MSG::VERBOSE << "Calling '" << getListenerName((*itlist).iListener)
00198           << "' for incident [" << incident.type() << "]" << endreq;
00199 
00200       // handle exceptions if they occur
00201       try {
00202         (*itlist).iListener->handle(incident);
00203       }
00204       catch( const GaudiException& exc ) {
00205        log << MSG::ERROR << "Exception with tag=" << exc.tag() << " is caught " << endreq;
00206        log << MSG::ERROR <<  exc  << endreq;
00207        if ( (*itlist).rethrow ) { throw (exc); }
00208       }
00209       catch( const std::exception& exc ) {
00210        log << MSG::ERROR << "Standard std::exception is caught " << endreq;
00211        log << MSG::ERROR << exc.what()  << endreq;
00212        if ( (*itlist).rethrow ) { throw (exc); }
00213       }
00214       catch(...) {
00215        log << MSG::ERROR << "UNKNOWN Exception is caught " << endreq;
00216        if ( (*itlist).rethrow ) { throw; }
00217       }
00218       // check if at least one of the listeners is a one-shot
00219       weHaveToCleanUp |= itlist->singleShot;
00220     }
00221     if (weHaveToCleanUp) {
00222         // remove all the listeners that need to be removed from the list
00223         llist->remove_if( listenerToBeRemoved() );
00224         // if the list is empty, we can remove it
00225         if( llist->size() == 0) {
00226         delete llist;
00227         m_listenerMap.erase(itmap);
00228       }
00229     }
00230   } 
00231   m_currentIncidentType = NULL;
00232   return;
00233 }


Member Data Documentation

ListenerMap IncidentSvc::m_listenerMap [private]

Definition at line 63 of file IncidentSvc.h.

Referenced by addListener(), fireIncident(), removeListener(), and ~IncidentSvc().

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 66 of file IncidentSvc.h.

Referenced by fireIncident(), and removeListener().


The documentation for this class was generated from the following files:
Generated at Fri Jul 18 12:08:15 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004