|
Gaudi Framework, version v21r6 |
| Home | Generated: 11 Nov 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 () |
| 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. | |
| 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 36 of file IncidentSvc.cpp.
00037 : base_class(name, svc), 00038 m_currentIncidentType(0), 00039 m_log(msgSvc(), name) 00040 { 00041 }
| IncidentSvc::~IncidentSvc | ( | ) | [virtual] |
Definition at line 43 of file IncidentSvc.cpp.
00043 { 00044 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00045 00046 for (ListenerMap::iterator i = m_listenerMap.begin(); 00047 i != m_listenerMap.end(); 00048 ++i) { 00049 delete i->second; 00050 } 00051 }
| StatusCode IncidentSvc::initialize | ( | ) | [virtual] |
Reimplemented from Service.
Definition at line 57 of file IncidentSvc.cpp.
00057 { 00058 // initialize the Service Base class 00059 StatusCode sc = Service::initialize(); 00060 if ( sc.isFailure() ) { 00061 return sc; 00062 } 00063 00064 m_log.setLevel(outputLevel()); 00065 m_currentIncidentType = 0; 00066 00067 // set my own (IncidentSvc) properties via the jobOptionService 00068 sc = setProperties(); 00069 if ( sc.isFailure() ) { 00070 m_log << MSG::ERROR << "Could not set my properties" << endmsg; 00071 return sc; 00072 } 00073 00074 return StatusCode::SUCCESS; 00075 }
| StatusCode IncidentSvc::finalize | ( | void | ) | [virtual] |
Reimplemented from Service.
Definition at line 77 of file IncidentSvc.cpp.
00077 { 00078 // Finalize this specific service 00079 StatusCode sc = Service::finalize(); 00080 if ( sc.isFailure() ) { 00081 return sc; 00082 } 00083 00084 return StatusCode::SUCCESS; 00085 }
| 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 91 of file IncidentSvc.cpp.
00092 { 00093 00094 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00095 00096 std::string ltype; 00097 if( type == "" ) ltype = "ALL"; 00098 else ltype = type; 00099 // find if the type already exists 00100 ListenerMap::iterator itMap = m_listenerMap.find( ltype ); 00101 if( itMap == m_listenerMap.end() ) { 00102 // if not found, create and insert now a list of listeners 00103 ListenerList* newlist = new ListenerList(); 00104 std::pair<ListenerMap::iterator, bool> p; 00105 p = m_listenerMap.insert(ListenerMap::value_type(ltype, newlist)); 00106 if( p.second ) itMap = p.first; 00107 } 00108 ListenerList* llist = (*itMap).second; 00109 // add Listener in the ListenerList according to the priority 00110 ListenerList::iterator itlist; 00111 for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) { 00112 if( (*itlist).priority < prio ) { 00113 // We insert before the current position 00114 break; 00115 } 00116 } 00117 00118 m_log << MSG::DEBUG << "Adding [" << type << "] listener '" << getListenerName(lis) 00119 << "' with priority " << prio << endmsg; 00120 00121 llist->insert(itlist, Listener(lis, prio, rethrow, singleShot)); 00122 }
| void IncidentSvc::removeListener | ( | IIncidentListener * | lis, | |
| const std::string & | type = "" | |||
| ) | [virtual] |
Remove listener.
Implements IIncidentSvc.
Definition at line 124 of file IncidentSvc.cpp.
00124 { 00125 00126 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00127 00128 if( type == "") { 00129 // remove Listener from all the lists 00130 ListenerMap::iterator itmap; 00131 for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();) { 00132 // since the current entry may be eventually deleted 00133 // we need to keep a memory of the next index before calling recursively this method 00134 ListenerMap::iterator itmap_old = itmap; 00135 itmap++; 00136 removeListener( lis, (*itmap_old).first ); 00137 } 00138 } 00139 else { 00140 ListenerMap::iterator itmap = m_listenerMap.find( type ); 00141 00142 if( itmap == m_listenerMap.end() ) { 00143 // if not found the incident type then return 00144 return; 00145 } 00146 else { 00147 ListenerList* llist = (*itmap).second; 00148 ListenerList::iterator itlist; 00149 bool justScheduleForRemoval = ( 0!= m_currentIncidentType ) 00150 && (type == *m_currentIncidentType); 00151 // loop over all the entries in the Listener list to remove all of them than matches 00152 // the listener address. Remember the next index before erasing the current one 00153 for( itlist = llist->begin(); itlist != llist->end(); ) { 00154 if( (*itlist).iListener == lis || lis == 0) { 00155 if (justScheduleForRemoval) { 00156 (itlist++)->singleShot = true; // remove it as soon as it is safe 00157 } 00158 else { 00159 m_log << MSG::DEBUG << "Removing [" << type << "] listener '" 00160 << getListenerName(lis) << "'" << endmsg; 00161 itlist = llist->erase(itlist); // remove from the list now 00162 } 00163 } 00164 else { 00165 itlist++; 00166 } 00167 } 00168 if( llist->size() == 0) { 00169 delete llist; 00170 m_listenerMap.erase(itmap); 00171 } 00172 } 00173 } 00174 }
| void IncidentSvc::fireIncident | ( | const Incident & | incident | ) | [virtual] |
Fire an Incident.
| Incident | being fired |
Implements IIncidentSvc.
Definition at line 242 of file IncidentSvc.cpp.
00242 { 00243 00244 // Call specific listeners 00245 i_fireIncident(incident, incident.type()); 00246 // Try listeners registered for ALL incidents 00247 if ( incident.type() != "ALL" ){ // avoid double calls if somebody fires the incident "ALL" 00248 i_fireIncident(incident, "ALL"); 00249 } 00250 }
| void IncidentSvc::i_fireIncident | ( | const Incident & | incident, | |
| const std::string & | type | |||
| ) | [private] |
Internal function to allow incidents listening to all events.
Definition at line 186 of file IncidentSvc.cpp.
00186 { 00187 00188 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00189 00190 ListenerMap::iterator itmap = m_listenerMap.find( listenerType ); 00191 if ( m_listenerMap.end() == itmap ) return; 00192 00193 // setting this pointer will avoid that a call to removeListener() during 00194 // the loop triggers a segfault 00195 m_currentIncidentType = &(incident.type()); 00196 00197 ListenerList* llist = (*itmap).second; 00198 ListenerList::iterator itlist; 00199 bool weHaveToCleanUp = false; 00200 // loop over all registered Listeners 00201 for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) { 00202 m_log << MSG::VERBOSE << "Calling '" << getListenerName((*itlist).iListener) 00203 << "' for incident [" << incident.type() << "]" << endmsg; 00204 00205 // handle exceptions if they occur 00206 try { 00207 (*itlist).iListener->handle(incident); 00208 } 00209 catch( const GaudiException& exc ) { 00210 m_log << MSG::ERROR << "Exception with tag=" << exc.tag() << " is caught" 00211 " handling incident" << m_currentIncidentType << endmsg; 00212 m_log << MSG::ERROR << exc << endmsg; 00213 if ( (*itlist).rethrow ) { throw (exc); } 00214 } 00215 catch( const std::exception& exc ) { 00216 m_log << MSG::ERROR << "Standard std::exception is caught" 00217 " handling incident" << m_currentIncidentType << endmsg; 00218 m_log << MSG::ERROR << exc.what() << endmsg; 00219 if ( (*itlist).rethrow ) { throw (exc); } 00220 } 00221 catch(...) { 00222 m_log << MSG::ERROR << "UNKNOWN Exception is caught" 00223 " handling incident" << m_currentIncidentType << endmsg; 00224 if ( (*itlist).rethrow ) { throw; } 00225 } 00226 // check if at least one of the listeners is a one-shot 00227 weHaveToCleanUp |= itlist->singleShot; 00228 } 00229 if (weHaveToCleanUp) { 00230 // remove all the listeners that need to be removed from the list 00231 llist->remove_if( listenerToBeRemoved() ); 00232 // if the list is empty, we can remove it 00233 if( llist->size() == 0) { 00234 delete llist; 00235 m_listenerMap.erase(itmap); 00236 } 00237 } 00238 00239 m_currentIncidentType = 0; 00240 }
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 74 of file IncidentSvc.h.
MsgStream IncidentSvc::m_log [private] |
boost::recursive_mutex IncidentSvc::m_listenerMapMutex [private] |