IncidentSvc Class Reference

Default implementation of the IIncidentSvc interface. More...

#include <src/IncidentSvc/IncidentSvc.h>

Inheritance diagram for IncidentSvc:
Collaboration diagram for IncidentSvc:

Classes

struct  Listener
 

Public Member Functions

StatusCode initialize () override
 
StatusCode finalize () override
 
void addListener (IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false) override
 
void removeListener (IIncidentListener *l, const std::string &type="") override
 
void fireIncident (const Incident &incident) override
 
void getListeners (std::vector< IIncidentListener * > &lis, const std::string &type="") const override
 
 IncidentSvc (const std::string &name, ISvcLocator *svc)
 
 ~IncidentSvc () override
 
- Public Member Functions inherited from extends< BASE, Interfaces >
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
 ~extends () override=default
 Virtual destructor. More...
 
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
 ~extends () override=default
 Virtual destructor. More...
 
- Public Member Functions inherited from extend_interfaces< Interfaces...>
 ~extend_interfaces () override=default
 Virtual destructor. More...
 
 ~extend_interfaces () override=default
 Virtual destructor. More...
 

Private Types

typedef std::vector< ListenerListenerList
 
typedef GaudiUtils::HashMap< Gaudi::StringKey, std::unique_ptr< ListenerList > > ListenerMap
 

Private Member Functions

ListenerMap::iterator removeListenerFromList (ListenerMap::iterator, IIncidentListener *item, bool scheduleRemoval)
 
void i_fireIncident (const Incident &incident, const std::string &type)
 Internal function to allow incidents listening to all events. More...
 

Private Attributes

ListenerMap m_listenerMap
 List of auditor names. More...
 
const std::string * m_currentIncidentType = nullptr
 Incident being fired. More...
 
std::recursive_mutex m_listenerMapMutex
 Mutex to synchronize access to m_listenerMap. More...
 
ChronoEntity m_timer
 timer & it's lock More...
 
bool m_timerLock = false
 

Additional Inherited Members

- Public Types inherited from extends< BASE, Interfaces >
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces...>
 Typedef to the base of this class. More...
 
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces...>
 Typedef to the base of this class. More...
 
- Public Types inherited from extend_interfaces< Interfaces...>
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids...>::type
 take union of the ext_iids of all Interfaces... More...
 
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids...>::type
 take union of the ext_iids of all Interfaces... More...
 

Detailed Description

Default implementation of the IIncidentSvc interface.

This implementation is thread-safe with the following features:

Definition at line 33 of file IncidentSvc.h.

Member Typedef Documentation

typedef std::vector<Listener> IncidentSvc::ListenerList
private

Definition at line 49 of file IncidentSvc.h.

Definition at line 50 of file IncidentSvc.h.

Constructor & Destructor Documentation

IncidentSvc::IncidentSvc ( const std::string &  name,
ISvcLocator svc 
)

Definition at line 51 of file IncidentSvc.cpp.

52  : base_class(name, svc)
53 {}
extends base_class
Typedef to this class.
Definition: extends.h:14
IncidentSvc::~IncidentSvc ( )
override

Definition at line 55 of file IncidentSvc.cpp.

56 {
57  std::unique_lock<std::recursive_mutex> lock(m_listenerMapMutex);
58 }
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
Definition: IncidentSvc.h:93
def lock(file)
Definition: locker.py:16

Member Function Documentation

void IncidentSvc::addListener ( IIncidentListener lis,
const std::string &  type = "",
long  priority = 0,
bool  rethrow = false,
bool  singleShot = false 
)
override

Definition at line 94 of file IncidentSvc.cpp.

97 {
98  static const std::string all{ "ALL" };
99  std::unique_lock<std::recursive_mutex> lock(m_listenerMapMutex);
100 
101  const std::string& ltype = ( !type.empty() ? type : all );
102 
103  // find if the type already exists
104  auto itMap = m_listenerMap.find( ltype );
105  if( itMap == m_listenerMap.end() ) {
106  // if not found, create and insert now a list of listeners
107  auto p = m_listenerMap.insert( { ltype, std::unique_ptr<ListenerList>( new ListenerList() ) } );
108  if ( !p.second ) { /* OOPS */ }
109  itMap = p.first;
110  }
111  auto& llist = *itMap->second;
112  // add Listener ordered by priority -- higher priority first,
113  // and then add behind listeneres with the same priority
114  // -- so we skip over all items with higher or same priority
115  auto i = std::partition_point( std::begin(llist),std::end(llist),
116  [&](const Listener& j) { return j.priority >= prio; } );
117  // We insert before the current position
118  DEBMSG << "Adding [" << type << "] listener '" << getListenerName(lis)
119  << "' with priority " << prio << endmsg;
120  llist.emplace(i, lis, prio, rethrow, singleShot);
121 }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
#define DEBMSG
Definition: IncidentSvc.cpp:45
iterator end()
Definition: Map.h:132
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
Definition: IncidentSvc.h:93
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
iterator find(const key_type &key)
Definition: Map.h:149
def lock(file)
Definition: locker.py:16
std::vector< Listener > ListenerList
Definition: IncidentSvc.h:49
std::pair< iterator, bool > insert(ValueType &&val)
Definition: Map.h:168
ListenerMap m_listenerMap
List of auditor names.
Definition: IncidentSvc.h:86
list i
Definition: ana.py:128
string type
Definition: gaudirun.py:151
StatusCode IncidentSvc::finalize ( )
override

Definition at line 80 of file IncidentSvc.cpp.

81 {
82  DEBMSG << m_timer.outputUserTime( "Incident timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
83  << m_timer.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
84 
85  // Finalize this specific service
87  if ( UNLIKELY(sc.isFailure()) ) { return sc; }
88 
89  return StatusCode::SUCCESS;
90 }
ChronoEntity m_timer
timer & it's lock
Definition: IncidentSvc.h:96
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode finalize() override
Definition: Service.cpp:188
#define DEBMSG
Definition: IncidentSvc.cpp:45
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
std::string outputUserTime() const
print the chrono ;
#define UNLIKELY(x)
Definition: Kernel.h:126
void IncidentSvc::fireIncident ( const Incident incident)
override

Definition at line 246 of file IncidentSvc.cpp.

247 {
248 
250 
251  // Call specific listeners
252  i_fireIncident(incident, incident.type());
253  // Try listeners registered for ALL incidents
254  if ( incident.type() != "ALL" ){ // avoid double calls if somebody fires the incident "ALL"
255  i_fireIncident(incident, "ALL");
256  }
257 }
ChronoEntity m_timer
timer & it's lock
Definition: IncidentSvc.h:96
const std::string & type() const
Access to the incident type.
Definition: Incident.h:34
bool m_timerLock
Definition: IncidentSvc.h:97
Helper object, useful for measurement of CPU-performance of highly-recursive structures, e.g.
Definition: LockedChrono.h:52
void i_fireIncident(const Incident &incident, const std::string &type)
Internal function to allow incidents listening to all events.
void IncidentSvc::getListeners ( std::vector< IIncidentListener * > &  lis,
const std::string &  type = "" 
) const
override

Definition at line 261 of file IncidentSvc.cpp.

263 {
264  static const std::string ALL { "ALL" };
265  std::unique_lock<std::recursive_mutex> lock(m_listenerMapMutex);
266 
267  const std::string& ltype = ( !type.empty() ? type : ALL );
268 
269  l.clear();
270  auto i = m_listenerMap.find( ltype );
271  if (i != m_listenerMap.end()) {
272  l.reserve(i->second->size());
273  std::transform( std::begin(*i->second), std::end(*i->second),
274  std::back_inserter(l),
275  [](const Listener& j) { return j.iListener; });
276  }
277 }
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
iterator end()
Definition: Map.h:132
int ALL
message levels --------------------------------------------------------—
Definition: Constants.py:11
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
Definition: IncidentSvc.h:93
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
iterator find(const key_type &key)
Definition: Map.h:149
def lock(file)
Definition: locker.py:16
dictionary l
Definition: gaudirun.py:421
ListenerMap m_listenerMap
List of auditor names.
Definition: IncidentSvc.h:86
list i
Definition: ana.py:128
string type
Definition: gaudirun.py:151
void IncidentSvc::i_fireIncident ( const Incident incident,
const std::string &  type 
)
private

Internal function to allow incidents listening to all events.

Definition at line 174 of file IncidentSvc.cpp.

176 {
177 
178  std::unique_lock<std::recursive_mutex> lock(m_listenerMapMutex);
179 
180  // Wouldn't it be better to write a small 'ReturnCode' service which
181  // looks for these 'special' incidents and does whatever needs to
182  // be done instead of making a special case here?
183 
184  // Special case: FailInputFile incident must set the application return code
185  if ( incident.type() == IncidentType::FailInputFile ||
186  incident.type() == IncidentType::CorruptedInputFile ) {
187  auto appmgr = serviceLocator()->as<IProperty>();
189  incident.type() == IncidentType::FailInputFile ?
192  ).ignore();
193  }
194 
195  auto ilisteners = m_listenerMap.find( listenerType );
196  if ( m_listenerMap.end() == ilisteners ) return;
197 
198  // setting this pointer will avoid that a call to removeListener() during
199  // the loop triggers a segfault
200  m_currentIncidentType = &incident.type();
201 
202  bool firedSingleShot = false;
203 
204  auto& listeners = *ilisteners->second;
205 
206  for( auto& listener : listeners )
207  {
208 
209  VERMSG << "Calling '" << getListenerName(listener.iListener)
210  << "' for incident [" << incident.type() << "]" << endmsg;
211 
212  // handle exceptions if they occur
213  try {
214  listener.iListener->handle(incident);
215  }
216  catch( const GaudiException& exc ) {
217  error() << "Exception with tag=" << exc.tag() << " is caught"
218  " handling incident" << m_currentIncidentType << endmsg;
219  error() << exc << endmsg;
220  if ( listener.rethrow ) { throw exc; }
221  }
222  catch( const std::exception& exc ) {
223  error() << "Standard std::exception is caught"
224  " handling incident" << m_currentIncidentType << endmsg;
225  error() << exc.what() << endmsg;
226  if ( listener.rethrow ) { throw exc; }
227  }
228  catch(...) {
229  error() << "UNKNOWN Exception is caught"
230  " handling incident" << m_currentIncidentType << endmsg;
231  if ( listener.rethrow ) { throw; }
232  }
233  // check wheter one of the listeners is singleShot
234  firedSingleShot |= listener.singleShot;
235  }
236  if (firedSingleShot) {
237  // remove all the singleshot listeners that got there shot...
238  listeners.erase( std::remove_if( std::begin(listeners),std::end(listeners), isSingleShot ),
239  std::end(listeners) ) ;
240  if (listeners.empty()) m_listenerMap.erase(ilisteners);
241  }
242 
243  m_currentIncidentType = nullptr;
244 }
Define general base for Gaudi exception.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const std::string & type() const
Access to the incident type.
Definition: Incident.h:34
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
constexpr int CorruptedInput
Definition: AppReturnCode.h:28
iterator end()
Definition: Map.h:132
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
Definition: IncidentSvc.h:93
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
constexpr int FailInput
Definition: AppReturnCode.h:23
iterator find(const key_type &key)
Definition: Map.h:149
def lock(file)
Definition: locker.py:16
virtual const std::string & tag() const
name tag for the exception, or exception type
const std::string * m_currentIncidentType
Incident being fired.
Definition: IncidentSvc.h:90
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:50
iterator erase(const_iterator pos)
Definition: Map.h:175
#define VERMSG
Definition: IncidentSvc.cpp:46
ListenerMap m_listenerMap
List of auditor names.
Definition: IncidentSvc.h:86
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
StatusCode IncidentSvc::initialize ( )
override

Definition at line 62 of file IncidentSvc.cpp.

63 {
64  // initialize the Service Base class
66  if ( sc.isFailure() ) return sc;
67 
68  m_currentIncidentType = nullptr;
69 
70  // set my own (IncidentSvc) properties via the jobOptionService
71  sc = setProperties();
72  if ( UNLIKELY(sc.isFailure()) )
73  {
74  error() << "Could not set my properties" << endmsg;
75  return sc;
76  }
77  return StatusCode::SUCCESS;
78 }
StatusCode initialize() override
Definition: Service.cpp:63
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
const std::string * m_currentIncidentType
Incident being fired.
Definition: IncidentSvc.h:90
#define UNLIKELY(x)
Definition: Kernel.h:126
void IncidentSvc::removeListener ( IIncidentListener l,
const std::string &  type = "" 
)
override

Definition at line 148 of file IncidentSvc.cpp.

150 {
151  std::unique_lock<std::recursive_mutex> lock(m_listenerMapMutex);
152 
153  bool scheduleForRemoval = ( m_currentIncidentType
154  && type == *m_currentIncidentType );
155  if( type.empty() ) {
156  auto i = std::begin(m_listenerMap);
157  while ( i != std::end(m_listenerMap) ) {
158  i = removeListenerFromList( i, lis, scheduleForRemoval );
159  }
160  } else {
161  auto i = m_listenerMap.find( type );
162  if ( i != m_listenerMap.end() ) removeListenerFromList( i, lis, scheduleForRemoval );
163  }
164 }
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
ListenerMap::iterator removeListenerFromList(ListenerMap::iterator, IIncidentListener *item, bool scheduleRemoval)
iterator end()
Definition: Map.h:132
std::recursive_mutex m_listenerMapMutex
Mutex to synchronize access to m_listenerMap.
Definition: IncidentSvc.h:93
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
iterator find(const key_type &key)
Definition: Map.h:149
def lock(file)
Definition: locker.py:16
const std::string * m_currentIncidentType
Incident being fired.
Definition: IncidentSvc.h:90
ListenerMap m_listenerMap
List of auditor names.
Definition: IncidentSvc.h:86
list i
Definition: ana.py:128
string type
Definition: gaudirun.py:151
IncidentSvc::ListenerMap::iterator IncidentSvc::removeListenerFromList ( ListenerMap::iterator  i,
IIncidentListener item,
bool  scheduleRemoval 
)
private

Definition at line 124 of file IncidentSvc.cpp.

127 {
128  auto match = [&](ListenerList::const_reference j )
129  { return !item || item == j.iListener; };
130 
131  auto& c = *(i->second);
132  if (!scheduleRemoval) {
133  ON_DEBUG std::for_each( std::begin(c), std::end(c),
134  [&](ListenerList::const_reference j) {
135  if (match(j)) debug() << "Removing [" << i->first << "] listener '"
136  << getListenerName(j.iListener) << "'" << endmsg;
137  });
138  c.erase( std::remove_if( std::begin(c), std::end(c), match ),
139  std::end(c) );
140  } else {
141  std::for_each( std::begin(c), std::end(c), [&](Listener& i) {
142  if (match(i)) i.singleShot = true; // will trigger removal as soon as it is safe
143  });
144  }
145  return c.empty() ? m_listenerMap.erase(i) : std::next(i);
146 }
tuple c
Definition: gaudirun.py:391
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
#define ON_DEBUG
Definition: IncidentSvc.cpp:42
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
iterator erase(const_iterator pos)
Definition: Map.h:175
ListenerMap m_listenerMap
List of auditor names.
Definition: IncidentSvc.h:86
list i
Definition: ana.py:128

Member Data Documentation

const std::string* IncidentSvc::m_currentIncidentType = nullptr
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 90 of file IncidentSvc.h.

ListenerMap IncidentSvc::m_listenerMap
private

List of auditor names.

Definition at line 86 of file IncidentSvc.h.

std::recursive_mutex IncidentSvc::m_listenerMapMutex
mutableprivate

Mutex to synchronize access to m_listenerMap.

Definition at line 93 of file IncidentSvc.h.

ChronoEntity IncidentSvc::m_timer
mutableprivate

timer & it's lock

Definition at line 96 of file IncidentSvc.h.

bool IncidentSvc::m_timerLock = false
mutableprivate

Definition at line 97 of file IncidentSvc.h.


The documentation for this class was generated from the following files: