![]() |
|
|
Generated: 8 Jan 2009 |
#include <IncidentSvc.h>


This implementation is thread-safe with the following features:
Definition at line 28 of file IncidentSvc.h.
Public Types | |
| typedef std::list< Listener > | ListenerList |
| 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 |
| 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.
| 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 }
| 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.
| 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.
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.
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.
| 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 }
ListenerMap IncidentSvc::m_listenerMap [private] |
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.
MsgStream IncidentSvc::m_log [private] |
boost::recursive_mutex IncidentSvc::m_listenerMapMutex [private] |