25 static const std::string s_unknown =
"<unknown>";
29 return iNamed ? iNamed->name() : s_unknown;
33#define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
34#define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
36#define DEBMSG ON_DEBUG debug()
37#define VERMSG ON_VERBOSE verbose()
52 static const std::string all{
"ALL" };
55 const std::string& ltype = ( !type.empty() ? type : all );
61 auto p =
m_listenerMap.insert( { ltype, std::make_unique<ListenerList>() } );
66 auto& llist = *itMap->second;
70 auto i = std::partition_point( std::begin( llist ), std::end( llist ),
71 [&](
const Listener& j ) {
return j.priority >= prio; } );
73 DEBMSG <<
"Adding [" << type <<
"] listener '" << getListenerName( lis ) <<
"' with priority " << prio <<
endmsg;
76IncidentSvc::ListenerMap::iterator
78 auto match = [&]( ListenerList::const_reference j ) {
return !item || item == j.iListener; };
80 auto& c = *( i->second );
81 if ( !scheduleRemoval ) {
82 ON_DEBUG std::for_each( std::begin( c ), std::end( c ), [&]( ListenerList::const_reference j ) {
84 debug() <<
"Removing [" << i->first <<
"] listener '" << getListenerName( j.iListener ) <<
"'" <<
endmsg;
86 c.erase( std::remove_if( std::begin( c ), std::end( c ), match ), std::end( c ) );
88 std::for_each( std::begin( c ), std::end( c ), [&]( Listener& i ) {
89 if ( match( i ) ) i.singleShot =
true;
108 constexpr struct isSingleShot_t {
109 bool operator()(
const IncidentSvc::Listener& l )
const {
return l.singleShot; }
121 if ( incident.
type() == IncidentType::FailInputFile || incident.
type() == IncidentType::CorruptedInputFile ) {
135 std::string curIncTyp;
139 curIncTyp =
"UNKNOWN";
142 bool firedSingleShot =
false;
144 auto& listeners = *ilisteners->second;
146 for (
auto& listener : listeners ) {
148 VERMSG <<
"Calling '" << getListenerName( listener.iListener ) <<
"' for incident [" << incident.
type() <<
"]"
153 listener.iListener->handle( incident );
155 error() <<
"Exception with tag=" << exc.
tag()
157 " handling incident "
158 << curIncTyp <<
" in listener " << getListenerName( listener.iListener ) <<
endmsg;
160 if ( listener.rethrow ) {
throw exc; }
161 }
catch (
const std::exception& exc ) {
162 error() <<
"Standard std::exception is caught"
163 " handling incident "
164 << curIncTyp <<
" in listener " << getListenerName( listener.iListener ) <<
endmsg;
166 if ( listener.rethrow ) {
throw exc; }
168 error() <<
"UNKNOWN Exception is caught"
169 " handling incident "
170 << curIncTyp <<
" in listener " << getListenerName( listener.iListener ) <<
endmsg;
171 if ( listener.rethrow ) {
throw; }
174 firedSingleShot |= listener.singleShot;
176 if ( firedSingleShot ) {
178 listeners.erase( std::remove_if( std::begin( listeners ), std::end( listeners ), isSingleShot ),
179 std::end( listeners ) );
192 if ( incident.
type() !=
"ALL" ) {
199 DEBMSG <<
"Async incident '" << incident->type() <<
"' fired on context " << ctx <<
endmsg;
204 auto [slotItr, inserted2] =
m_slotEvent.insert( { ctx.slot(), ctx.evt() } );
207 if ( slotItr->second != ctx.evt() ) {
208 slotItr->second = ctx.evt();
211 debug() <<
"Clearing remaining obsolete incidents from slot " << ctx.slot() <<
":";
212 std::unique_ptr<Incident> inc;
213 while ( incItr->second.try_pop( inc ) ) {
debug() <<
" " << inc->type() <<
"(" << inc->context() <<
")"; }
216 incItr->second.clear();
218 incItr->second.push( std::move( incident ) );
222 static const std::string ALL{
"ALL" };
225 const std::string& ltype = ( !type.empty() ? type : ALL );
230 l.reserve( i->second->size() );
231 std::transform( std::begin( *i->second ), std::end( *i->second ), std::back_inserter( l ),
232 [](
const Listener& j ) { return j.iListener; } );
241 std::unique_ptr<Incident> inc;
243 DEBMSG <<
"Collecting listeners fired on context " << *ctx <<
endmsg;
244 while ( incs->second.try_pop( inc ) ) {
246 if ( inc->context().evt() == ctx->evt() ) {
250 p.emplace_back( std::move( inc ), std::vector<Listener>{ i->second->begin(), i->second->end() } );
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MSG::Level msgLevel() const
This class represents an entry point to all the event specific data.
Helper object, useful for measurement of CPU-performance of highly-recursive structures,...
Define general base for Gaudi exception.
const char * what() const override
method from std::exception
virtual const std::string & tag() const
name tag for the exception, or exception type
The interface implemented by any class wanting to listen to Incidents.
std::vector< std::pair< std::unique_ptr< Incident >, std::vector< Listener > > > IncidentPack
List of incidents and their listeners.
The IProperty is the basic interface for all components which have properties that can be set or get.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Base class for all Incidents (computing events).
const std::string & type() const
Access to the incident type.
Default implementation of the IIncidentSvc interface.
void removeListener(IIncidentListener *l, const std::string &type="") override
StatusCode finalize() override
tbb::concurrent_queue< std::unique_ptr< Incident > > IncQueue_t
ListenerMap::iterator removeListenerFromList(ListenerMap::iterator, IIncidentListener *item, bool scheduleRemoval)
IIncidentSvc::IncidentPack getIncidents(const EventContext *ctx) override
tbb::concurrent_unordered_map< EventContext::ContextID_t, EventContext::ContextEvt_t > m_slotEvent
Event ID for each slot.
tbb::concurrent_unordered_map< EventContext::ContextID_t, IncQueue_t > m_firedIncidents
void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false) override
const std::string * m_currentIncidentType
Incident being fired.
ChronoEntity m_timer
timer & it's lock
void i_fireIncident(const Incident &incident, const std::string &type)
Internal function to allow incidents listening to all events.
ListenerMap m_listenerMap
List of auditor names.
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
IncidentSvc(const std::string &name, ISvcLocator *svc)
void fireIncident(const Incident &incident) override
void getListeners(std::vector< IIncidentListener * > &lis, const std::string &type="") const override
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
StatusCode finalize() override
const std::string & name() const override
Retrieve name of the service.
Small smart pointer class with automatic reference counting for IInterface.
This class is used for returning status codes from appropriate routines.
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
constexpr int CorruptedInput
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.