|
Gaudi Framework, version v21r8 |
| Home | Generated: 17 Mar 2010 |
#include <IncidentSvc.h>


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. | |
| MsgStream | m_log |
| Internal MsgStream. | |
| boost::recursive_mutex | m_listenerMapMutex |
| Mutex to synchronize access to m_listenerMap. | |
| ChronoEntity | m_timer |
| timer & it's lock | |
| bool | m_timerLock |
Classes | |
| struct | Listener |
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 44 of file IncidentSvc.cpp.
00045 : base_class(name, svc) 00046 , m_currentIncidentType(0) 00047 , m_log(msgSvc(), name) 00048 , m_timer() 00049 , m_timerLock ( false ) 00050 {}
| IncidentSvc::~IncidentSvc | ( | ) | [virtual] |
Definition at line 52 of file IncidentSvc.cpp.
00053 { 00054 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00055 00056 for (ListenerMap::iterator i = m_listenerMap.begin(); 00057 i != m_listenerMap.end(); 00058 ++i) { 00059 delete i->second; 00060 } 00061 }
| StatusCode IncidentSvc::initialize | ( | ) | [virtual] |
Reimplemented from Service.
Definition at line 65 of file IncidentSvc.cpp.
00066 { 00067 // initialize the Service Base class 00068 StatusCode sc = Service::initialize(); 00069 if ( sc.isFailure() ) { 00070 return sc; 00071 } 00072 00073 m_log.setLevel(outputLevel()); 00074 m_currentIncidentType = 0; 00075 00076 // set my own (IncidentSvc) properties via the jobOptionService 00077 sc = setProperties(); 00078 if ( sc.isFailure() ) 00079 { 00080 m_log << MSG::ERROR << "Could not set my properties" << endmsg; 00081 return sc; 00082 } 00083 00084 return StatusCode::SUCCESS; 00085 }
| StatusCode IncidentSvc::finalize | ( | void | ) | [virtual] |
Reimplemented from Service.
Definition at line 87 of file IncidentSvc.cpp.
00088 { 00089 m_log 00090 << MSG::DEBUG 00091 << m_timer.outputUserTime 00092 ( "Incident timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec ) 00093 << m_timer.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ; 00094 00095 // Finalize this specific service 00096 StatusCode sc = Service::finalize(); 00097 if ( sc.isFailure() ) { return sc; } 00098 00099 return StatusCode::SUCCESS; 00100 }
| 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 105 of file IncidentSvc.cpp.
00108 { 00109 00110 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00111 00112 std::string ltype; 00113 if( type == "" ) ltype = "ALL"; 00114 else ltype = type; 00115 // find if the type already exists 00116 ListenerMap::iterator itMap = m_listenerMap.find( ltype ); 00117 if( itMap == m_listenerMap.end() ) { 00118 // if not found, create and insert now a list of listeners 00119 ListenerList* newlist = new ListenerList(); 00120 std::pair<ListenerMap::iterator, bool> p; 00121 p = m_listenerMap.insert(ListenerMap::value_type(ltype, newlist)); 00122 if( p.second ) itMap = p.first; 00123 } 00124 ListenerList* llist = (*itMap).second; 00125 // add Listener in the ListenerList according to the priority 00126 ListenerList::iterator itlist; 00127 for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) { 00128 if( (*itlist).priority < prio ) { 00129 // We insert before the current position 00130 break; 00131 } 00132 } 00133 00134 m_log << MSG::DEBUG << "Adding [" << type << "] listener '" << getListenerName(lis) 00135 << "' with priority " << prio << endmsg; 00136 00137 llist->insert(itlist, Listener(lis, prio, rethrow, singleShot)); 00138 }
| void IncidentSvc::removeListener | ( | IIncidentListener * | lis, | |
| const std::string & | type = "" | |||
| ) | [virtual] |
Remove listener.
Implements IIncidentSvc.
Definition at line 141 of file IncidentSvc.cpp.
00143 { 00144 00145 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00146 00147 if( type == "") { 00148 // remove Listener from all the lists 00149 ListenerMap::iterator itmap; 00150 for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();) 00151 { 00152 // since the current entry may be eventually deleted 00153 // we need to keep a memory of the next index before 00154 // calling recursively this method 00155 ListenerMap::iterator itmap_old = itmap; 00156 itmap++; 00157 removeListener( lis, (*itmap_old).first ); 00158 } 00159 } 00160 else { 00161 ListenerMap::iterator itmap = m_listenerMap.find( type ); 00162 00163 if( itmap == m_listenerMap.end() ) { 00164 // if not found the incident type then return 00165 return; 00166 } 00167 else { 00168 ListenerList* llist = (*itmap).second; 00169 ListenerList::iterator itlist; 00170 bool justScheduleForRemoval = ( 0!= m_currentIncidentType ) 00171 && (type == *m_currentIncidentType); 00172 // loop over all the entries in the Listener list 00173 // to remove all of them than matches 00174 // the listener address. Remember the next index 00175 // before erasing the current one 00176 for( itlist = llist->begin(); itlist != llist->end(); ) { 00177 if( (*itlist).iListener == lis || lis == 0) { 00178 if (justScheduleForRemoval) { 00179 (itlist++)->singleShot = true; // remove it as soon as it is safe 00180 } 00181 else { 00182 m_log << MSG::DEBUG << "Removing [" << type << "] listener '" 00183 << getListenerName(lis) << "'" << endmsg; 00184 itlist = llist->erase(itlist); // remove from the list now 00185 } 00186 } 00187 else { 00188 itlist++; 00189 } 00190 } 00191 if( llist->size() == 0) { 00192 delete llist; 00193 m_listenerMap.erase(itmap); 00194 } 00195 } 00196 } 00197 }
| void IncidentSvc::fireIncident | ( | const Incident & | incident | ) | [virtual] |
Fire an Incident.
| Incident | being fired |
Implements IIncidentSvc.
Definition at line 278 of file IncidentSvc.cpp.
00279 { 00280 00281 Gaudi::Utils::LockedChrono timer ( m_timer , m_timerLock ) ; 00282 00283 // Call specific listeners 00284 i_fireIncident(incident, incident.type()); 00285 // Try listeners registered for ALL incidents 00286 if ( incident.type() != "ALL" ){ // avoid double calls if somebody fires the incident "ALL" 00287 i_fireIncident(incident, "ALL"); 00288 } 00289 }
| void IncidentSvc::i_fireIncident | ( | const Incident & | incident, | |
| const std::string & | type | |||
| ) | [private] |
Internal function to allow incidents listening to all events.
Definition at line 210 of file IncidentSvc.cpp.
00212 { 00213 00214 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex); 00215 00216 ListenerMap::iterator itmap = m_listenerMap.find( listenerType ); 00217 if ( m_listenerMap.end() == itmap ) return; 00218 00219 // setting this pointer will avoid that a call to removeListener() during 00220 // the loop triggers a segfault 00221 m_currentIncidentType = &(incident.type()); 00222 00223 ListenerList* llist = (*itmap).second; 00224 ListenerList::iterator itlist; 00225 bool weHaveToCleanUp = false; 00226 // loop over all registered Listeners 00227 00228 const bool verbose = MSG::VERBOSE >= outputLevel() ; 00229 00230 for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) 00231 { 00232 00233 if ( verbose ) 00234 { 00235 m_log 00236 << MSG::VERBOSE 00237 << "Calling '" << getListenerName((*itlist).iListener) 00238 << "' for incident [" << incident.type() << "]" << endmsg; 00239 } 00240 00241 // handle exceptions if they occur 00242 try { 00243 (*itlist).iListener->handle(incident); 00244 } 00245 catch( const GaudiException& exc ) { 00246 m_log << MSG::ERROR << "Exception with tag=" << exc.tag() << " is caught" 00247 " handling incident" << m_currentIncidentType << endmsg; 00248 m_log << MSG::ERROR << exc << endmsg; 00249 if ( (*itlist).rethrow ) { throw (exc); } 00250 } 00251 catch( const std::exception& exc ) { 00252 m_log << MSG::ERROR << "Standard std::exception is caught" 00253 " handling incident" << m_currentIncidentType << endmsg; 00254 m_log << MSG::ERROR << exc.what() << endmsg; 00255 if ( (*itlist).rethrow ) { throw (exc); } 00256 } 00257 catch(...) { 00258 m_log << MSG::ERROR << "UNKNOWN Exception is caught" 00259 " handling incident" << m_currentIncidentType << endmsg; 00260 if ( (*itlist).rethrow ) { throw; } 00261 } 00262 // check if at least one of the listeners is a one-shot 00263 weHaveToCleanUp |= itlist->singleShot; 00264 } 00265 if (weHaveToCleanUp) { 00266 // remove all the listeners that need to be removed from the list 00267 llist->remove_if( listenerToBeRemoved() ); 00268 // if the list is empty, we can remove it 00269 if( llist->size() == 0) { 00270 delete llist; 00271 m_listenerMap.erase(itmap); 00272 } 00273 } 00274 00275 m_currentIncidentType = 0; 00276 }
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 94 of file IncidentSvc.h.
MsgStream IncidentSvc::m_log [private] |
boost::recursive_mutex IncidentSvc::m_listenerMapMutex [private] |
ChronoEntity IncidentSvc::m_timer [mutable, private] |
bool IncidentSvc::m_timerLock [mutable, private] |
Definition at line 104 of file IncidentSvc.h.