Gaudi Framework, version v20r4

Generated: 8 Jan 2009

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

Default implementation of the IIncidentSvc interface.

This implementation is thread-safe with the following features:

Definition at line 28 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 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.
MsgStream m_log
 Internal MsgStream.
boost::recursive_mutex m_listenerMapMutex
 Mutex to synchronize access to m_listenerMap.

Classes

struct  Listener

Member Typedef Documentation

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

Definition at line 44 of file IncidentSvc.h.

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

Definition at line 45 of file IncidentSvc.h.


Constructor & Destructor Documentation

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

Definition at line 30 of file IncidentSvc.cpp.

00031   : Service(name, svc),
00032     m_currentIncidentType(0),
00033     m_log(msgSvc(), name)
00034 {
00035 }

IncidentSvc::~IncidentSvc (  )  [virtual]

Definition at line 37 of file IncidentSvc.cpp.

00037                           {
00038   boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
00039   
00040   for (ListenerMap::iterator i = m_listenerMap.begin();
00041        i != m_listenerMap.end();
00042        ++i) {
00043     delete i->second;
00044   }
00045 }


Member Function Documentation

StatusCode IncidentSvc::initialize (  )  [virtual]

Initialization (from CONFIGURED to INITIALIZED).

Reimplemented from Service.

Definition at line 51 of file IncidentSvc.cpp.

00051                                    {
00052   // initialize the Service Base class
00053   StatusCode sc = Service::initialize();
00054   if ( sc.isFailure() ) {
00055     return sc;
00056   }
00057 
00058   m_log.setLevel(outputLevel());
00059   m_currentIncidentType = 0;
00060    
00061   // set my own (IncidentSvc) properties via the jobOptionService
00062   sc = setProperties();
00063   if ( sc.isFailure() ) {
00064     m_log << MSG::ERROR << "Could not set my properties" << endreq;
00065     return sc;
00066   }
00067 
00068   return StatusCode::SUCCESS;
00069 }

StatusCode IncidentSvc::finalize (  )  [virtual]

Finalize (from INITIALIZED to CONFIGURED).

Reimplemented from Service.

Definition at line 71 of file IncidentSvc.cpp.

00071                                  {
00072   // Finalize this specific service
00073   StatusCode sc = Service::finalize();
00074   if ( sc.isFailure() ) {
00075     return sc;
00076   }
00077 
00078   return StatusCode::SUCCESS;
00079 }

StatusCode IncidentSvc::queryInterface ( const InterfaceID riid,
void **  ppvUnknown 
) [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 81 of file IncidentSvc.cpp.

00081                                                                                      {
00082   if ( IID_IIncidentSvc == riid )    {
00083     *ppvInterface = (IIncidentSvc*)this;
00084   }
00085   else  {
00086     // Interface is not directly available: try out a base class
00087     return Service::queryInterface(riid, ppvInterface);
00088   }
00089   addRef();
00090   return StatusCode::SUCCESS;
00091 }

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 97 of file IncidentSvc.cpp.

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

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

Remove listener.

Parameters:
lis Listener address
type Incident type

Implements IIncidentSvc.

Definition at line 130 of file IncidentSvc.cpp.

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

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

Fire an Incident.

Parameters:
Incident being fired

Implements IIncidentSvc.

Definition at line 245 of file IncidentSvc.cpp.

00245                                                          {
00246     
00247   // Call specific listeners
00248   i_fireIncident(incident, incident.type());
00249   // Try listeners registered for ALL incidents
00250   if ( incident.type() != "ALL" ){ // avoid double calls if somebody fires the incident "ALL"
00251     i_fireIncident(incident, "ALL");
00252   }
00253 }

void IncidentSvc::i_fireIncident ( const Incident incident,
const std::string &  type 
) [private]

Internal function to allow incidents listening to all events.

Definition at line 192 of file IncidentSvc.cpp.

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


Member Data Documentation

List of auditor names.

Definition at line 71 of file IncidentSvc.h.

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

Internal MsgStream.

Definition at line 78 of file IncidentSvc.h.

boost::recursive_mutex IncidentSvc::m_listenerMapMutex [private]

Mutex to synchronize access to m_listenerMap.

Definition at line 81 of file IncidentSvc.h.


The documentation for this class was generated from the following files:

Generated at Thu Jan 8 17:51:40 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004