Go to the documentation of this file.00001
00002 #ifdef _WIN32
00003
00004
00005
00006 #define NOMSG
00007 #define NOGDI
00008 #endif
00009
00010
00011
00012 #include "GaudiKernel/MsgStream.h"
00013 #include "GaudiKernel/ISvcLocator.h"
00014 #include "GaudiKernel/SmartIF.h"
00015 #include "GaudiKernel/IIncidentListener.h"
00016 #include "GaudiKernel/Incident.h"
00017 #include "GaudiKernel/GaudiException.h"
00018 #include "GaudiKernel/LockedChrono.h"
00019 #include "GaudiKernel/AppReturnCode.h"
00020
00021
00022
00023 #include "IncidentSvc.h"
00024
00025
00026
00027 DECLARE_SERVICE_FACTORY(IncidentSvc)
00028
00029 namespace
00030 {
00031
00032 static const std::string s_unknown = "<unknown>" ;
00033
00034 inline const std::string& getListenerName ( IIncidentListener* lis )
00035 {
00036 SmartIF<INamedInterface> iNamed(lis);
00037 return iNamed.isValid() ? iNamed->name() : s_unknown ;
00038 }
00039
00040 }
00041
00042 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
00043 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
00044
00045 #define DEBMSG ON_DEBUG debug()
00046 #define VERMSG ON_VERBOSE verbose()
00047
00048
00049
00050
00051 IncidentSvc::IncidentSvc( const std::string& name, ISvcLocator* svc )
00052 : base_class(name, svc)
00053 , m_currentIncidentType(0)
00054 , m_timer()
00055 , m_timerLock ( false )
00056 {}
00057
00058 IncidentSvc::~IncidentSvc()
00059 {
00060 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
00061
00062 for (ListenerMap::iterator i = m_listenerMap.begin();
00063 i != m_listenerMap.end();
00064 ++i) {
00065 delete i->second;
00066 }
00067 }
00068
00069
00070
00071 StatusCode IncidentSvc::initialize()
00072 {
00073
00074 StatusCode sc = Service::initialize();
00075 if ( sc.isFailure() ) {
00076 return sc;
00077 }
00078
00079 m_currentIncidentType = 0;
00080
00081
00082 sc = setProperties();
00083 if ( UNLIKELY(sc.isFailure()) )
00084 {
00085 error() << "Could not set my properties" << endmsg;
00086 return sc;
00087 }
00088
00089 return StatusCode::SUCCESS;
00090 }
00091
00092 StatusCode IncidentSvc::finalize()
00093 {
00094 DEBMSG << m_timer.outputUserTime( "Incident timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00095 << m_timer.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00096
00097
00098 StatusCode sc = Service::finalize();
00099 if ( UNLIKELY(sc.isFailure()) ) { return sc; }
00100
00101 return StatusCode::SUCCESS;
00102 }
00103
00104
00105
00106 void IncidentSvc::addListener
00107 ( IIncidentListener* lis ,
00108 const std::string& type ,
00109 long prio, bool rethrow, bool singleShot)
00110 {
00111
00112 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
00113
00114 std::string ltype;
00115 if( type == "" ) ltype = "ALL";
00116 else ltype = type;
00117
00118 ListenerMap::iterator itMap = m_listenerMap.find( ltype );
00119 if( itMap == m_listenerMap.end() ) {
00120
00121 ListenerList* newlist = new ListenerList();
00122 std::pair<ListenerMap::iterator, bool> p;
00123 p = m_listenerMap.insert(ListenerMap::value_type(ltype, newlist));
00124 if( p.second ) itMap = p.first;
00125 }
00126 ListenerList* llist = (*itMap).second;
00127
00128 ListenerList::iterator itlist;
00129 for( itlist = llist->begin(); itlist != llist->end(); itlist++ ) {
00130 if( (*itlist).priority < prio ) {
00131
00132 break;
00133 }
00134 }
00135
00136 DEBMSG << "Adding [" << type << "] listener '" << getListenerName(lis)
00137 << "' with priority " << prio << endmsg;
00138
00139 llist->insert(itlist, Listener(lis, prio, rethrow, singleShot));
00140 }
00141
00142 void IncidentSvc::removeListener
00143 ( IIncidentListener* lis ,
00144 const std::string& type )
00145 {
00146
00147 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
00148
00149 if( type == "") {
00150
00151 ListenerMap::iterator itmap;
00152 for ( itmap = m_listenerMap.begin(); itmap != m_listenerMap.end();)
00153 {
00154
00155
00156
00157 ListenerMap::iterator itmap_old = itmap;
00158 itmap++;
00159 removeListener( lis, (*itmap_old).first );
00160 }
00161 }
00162 else {
00163 ListenerMap::iterator itmap = m_listenerMap.find( type );
00164
00165 if( itmap == m_listenerMap.end() ) {
00166
00167 return;
00168 }
00169 else {
00170 ListenerList* llist = (*itmap).second;
00171 ListenerList::iterator itlist;
00172 bool justScheduleForRemoval = ( 0!= m_currentIncidentType )
00173 && (type == *m_currentIncidentType);
00174
00175
00176
00177
00178 for( itlist = llist->begin(); itlist != llist->end(); ) {
00179 if( (*itlist).iListener == lis || lis == 0) {
00180 if (justScheduleForRemoval) {
00181 (itlist++)->singleShot = true;
00182 }
00183 else {
00184 DEBMSG << "Removing [" << type << "] listener '"
00185 << getListenerName(lis) << "'" << endmsg;
00186 itlist = llist->erase(itlist);
00187 }
00188 }
00189 else {
00190 itlist++;
00191 }
00192 }
00193 if( llist->size() == 0) {
00194 delete llist;
00195 m_listenerMap.erase(itmap);
00196 }
00197 }
00198 }
00199 }
00200
00201 namespace {
00204 struct listenerToBeRemoved{
00205 inline bool operator() (const IncidentSvc::Listener& l) {
00206 return l.singleShot;
00207 }
00208 };
00209 }
00210
00211 void IncidentSvc::i_fireIncident
00212 ( const Incident& incident ,
00213 const std::string& listenerType )
00214 {
00215
00216 boost::recursive_mutex::scoped_lock lock(m_listenerMapMutex);
00217
00218
00219 if (incident.type() == IncidentType::FailInputFile) {
00220
00221 SmartIF<IProperty> appmgr(serviceLocator());
00222 Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::FailInput).ignore();
00223 }
00224
00225 ListenerMap::iterator itmap = m_listenerMap.find( listenerType );
00226 if ( m_listenerMap.end() == itmap ) return;
00227
00228
00229
00230 m_currentIncidentType = &(incident.type());
00231
00232 ListenerList* llist = (*itmap).second;
00233 ListenerList::iterator itlist;
00234 bool weHaveToCleanUp = false;
00235
00236
00237 for( itlist = llist->begin(); itlist != llist->end(); itlist++ )
00238 {
00239
00240 VERMSG << "Calling '" << getListenerName((*itlist).iListener)
00241 << "' for incident [" << incident.type() << "]" << endmsg;
00242
00243
00244 try {
00245 (*itlist).iListener->handle(incident);
00246 }
00247 catch( const GaudiException& exc ) {
00248 error() << "Exception with tag=" << exc.tag() << " is caught"
00249 " handling incident" << m_currentIncidentType << endmsg;
00250 error() << exc << endmsg;
00251 if ( (*itlist).rethrow ) { throw (exc); }
00252 }
00253 catch( const std::exception& exc ) {
00254 error() << "Standard std::exception is caught"
00255 " handling incident" << m_currentIncidentType << endmsg;
00256 error() << exc.what() << endmsg;
00257 if ( (*itlist).rethrow ) { throw (exc); }
00258 }
00259 catch(...) {
00260 error() << "UNKNOWN Exception is caught"
00261 " handling incident" << m_currentIncidentType << endmsg;
00262 if ( (*itlist).rethrow ) { throw; }
00263 }
00264
00265 weHaveToCleanUp |= itlist->singleShot;
00266 }
00267 if (weHaveToCleanUp) {
00268
00269 llist->remove_if( listenerToBeRemoved() );
00270
00271 if( llist->size() == 0) {
00272 delete llist;
00273 m_listenerMap.erase(itmap);
00274 }
00275 }
00276
00277 m_currentIncidentType = 0;
00278 }
00279
00280 void IncidentSvc::fireIncident( const Incident& incident )
00281 {
00282
00283 Gaudi::Utils::LockedChrono timer ( m_timer , m_timerLock ) ;
00284
00285
00286 i_fireIncident(incident, incident.type());
00287
00288 if ( incident.type() != "ALL" ){
00289 i_fireIncident(incident, "ALL");
00290 }
00291
00292 }
00293
00294
00295