CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MessageSender.cc
Go to the documentation of this file.
4 
6 
7 #include <algorithm>
8 #include <cassert>
9 #include <vector>
10 #include <limits>
11 #include <atomic>
12 
13 #include <functional>
14 #include "tbb/concurrent_unordered_map.h"
15 
16 
17 #define TRACE_DROP
18 #ifdef TRACE_DROP
19 #include <iostream>
20 #endif
21 
22 // Change log
23 //
24 // 1 mf 8/25/08 keeping the error summary information for
25 // LoggedErrorsSummary()
26 //
27 // 2 mf 11/2/10 Use new moduleContext method of MessageDrop:
28 // see MessageServer/src/MessageLogger.cc change 17.
29 //
30 
31 
32 using namespace edm;
33 
34 namespace {
35  //Helper class used as 'key' to the thread safe map storing the
36  // per event log error and log warning messages
37  struct ErrorSummaryMapKey {
40  ELseverityLevel severity;
41 
42  bool operator<(ErrorSummaryMapKey const& iOther) const {
43  int comp =severity.getLevel()-iOther.severity.getLevel();
44  if(0==comp) {
45  comp = category.compare(iOther.category);
46  if(comp == 0) {
47  comp = module.compare(iOther.module);
48  }
49  }
50  return comp < 0;
51  }
52 
53  bool operator==(ErrorSummaryMapKey const& iOther) const {
54  return ((0==category.compare(iOther.category)) and
55  (0==module.compare(iOther.module)) and
56  (severity.getLevel() ==iOther.severity.getLevel()));
57  }
58  size_t smallHash() const {
59  std::hash<std::string> h;
60 
61  return h( category+module+severity.getSymbol());
62  }
63 
64  struct key_hash {
65  std::size_t operator()(ErrorSummaryMapKey const& iKey) const{
66  return iKey.smallHash();
67  }
68  };
69  };
70 
71  class AtomicUnsignedInt {
72  public:
73  AtomicUnsignedInt() : value_(0) {}
74  AtomicUnsignedInt(AtomicUnsignedInt const& r) : value_(r.value_.load(std::memory_order_acquire)) {}
75  std::atomic<unsigned int>& value() { return value_; }
76  std::atomic<unsigned int> const& value() const { return value_; }
77  private:
78  std::atomic<unsigned int> value_;
79  };
80 
81 }
82 
83 [[cms::thread_safe]] static std::atomic<bool> errorSummaryIsBeingKept{false};
84 //Each item in the vector is reserved for a different Stream
85 [[cms::thread_safe]] static std::vector<tbb::concurrent_unordered_map<ErrorSummaryMapKey, AtomicUnsignedInt,ErrorSummaryMapKey::key_hash>> errorSummaryMaps;
86 
88  ELstring const & id,
89  bool verbatim, bool suppressed )
90 : errorobj_p( suppressed ? 0 : new ErrorObj(sev,id,verbatim), ErrorObjDeleter())
91 {
92  //std::cout << "MessageSender ctor; new ErrorObj at: " << errorobj_p << '\n';
93 }
94 
95 
96 // This destructor must not be permitted to throw. A
97 // boost::thread_resoruce_error is thrown at static destruction time,
98 // if the MessageLogger library is loaded -- even if it is not used.
100  if (errorObjPtr == 0) {
101  return;
102  }
103  try
104  {
105  //std::cout << "MessageSender dtor; ErrorObj at: " << errorobj_p << '\n';
106 
107  // surrender ownership of our ErrorObj, transferring ownership
108  // (via the intermediate MessageLoggerQ) to the MessageLoggerScribe
109  // that will (a) route the message text to its destination(s)
110  // and will then (b) dispose of the ErrorObj
111 
113  if (drop) {
114  errorObjPtr->setModule(drop->moduleContext()); // change log
115  errorObjPtr->setContext(drop->runEvent);
116  }
117 #ifdef TRACE_DROP
118  if (!drop) std::cerr << "MessageSender::~MessageSender() - Null drop pointer \n";
119 #endif
120  // change log 1
121  if ( errorSummaryIsBeingKept.load(std::memory_order_acquire) &&
122  errorObjPtr->xid().severity >= ELwarning &&
124  {
125  auto& errorSummaryMap =errorSummaryMaps[drop->streamID];
126 
127  ELextendedID const & xid = errorObjPtr->xid();
128  ErrorSummaryMapKey key {xid.id, xid.module, xid.severity};
129  auto i = errorSummaryMap.find(key);
130  if (i != errorSummaryMap.end()) {
131  i->second.value().fetch_add(1,std::memory_order_acq_rel); // same as ++errorSummaryMap[key]
132  } else {
133  errorSummaryMap[key].value().store(1,std::memory_order_release);
134  }
135  }
136 
137  MessageLoggerQ::MLqLOG(errorObjPtr);
138  }
139  catch ( ... )
140  {
141  // nothing to do
142 
143  // for test that removal of thread-involved static works,
144  // simply throw here, then run in trivial_main in totalview
145  // and Next or Step so that the exception would be detected.
146  // That test has been done 12/14/07.
147  }
148 }
150 {
151 }
152 
153 //The following functions are declared here rather than in
154 // LoggedErrorsSummary.cc because only MessageSender and these
155 // functions interact with the statics errorSummaryIsBeingKept and
156 // errorSummaryMaps. By putting them into the same .cc file the
157 // statics can be file scoped rather than class scoped and therefore
158 // better encapsulated.
159 namespace edm {
160 
162  bool ret = errorSummaryIsBeingKept.exchange(true,std::memory_order_acq_rel);
163  return ret;
164  }
165 
167  bool ret = errorSummaryIsBeingKept.exchange(false,std::memory_order_acq_rel);
168  return ret;
169  }
170 
171  bool FreshErrorsExist(unsigned int iStreamID) {
172  assert(iStreamID<errorSummaryMaps.size());
173  return errorSummaryMaps[iStreamID].size()>0;
174  }
175 
176  std::vector<ErrorSummaryEntry> LoggedErrorsSummary(unsigned int iStreamID) {
177  assert(iStreamID<errorSummaryMaps.size());
178  auto const& errorSummaryMap =errorSummaryMaps[iStreamID];
179  std::vector<ErrorSummaryEntry> v;
180  auto end = errorSummaryMap.end();
181  for (auto i = errorSummaryMap.begin();
182  i != end; ++i) {
183  auto const& key = i->first;
184  ErrorSummaryEntry e{key.category,key.module,key.severity};
185 
186  e.count = i->second.value().load(std::memory_order_acquire);
187  v.push_back(e);
188  }
189  std::sort(v.begin(),v.end());
190  return v;
191  }
192 
193  void clearLoggedErrorsSummary(unsigned int iStreamID) {
194  assert(iStreamID<errorSummaryMaps.size());
195  errorSummaryMaps[iStreamID].clear();
196  }
197 
198  void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax) {
199  assert(0==errorSummaryMaps.size());
200  errorSummaryMaps.resize(iMax);
201  }
202 
203 
204  std::vector<ErrorSummaryEntry> LoggedErrorsOnlySummary(unsigned int iStreamID) { // ChangeLog 2
205  std::vector<ErrorSummaryEntry> v;
206  assert(iStreamID < errorSummaryMaps.size());
207  auto const& errorSummaryMap =errorSummaryMaps[iStreamID];
208  auto end = errorSummaryMap.end();
209  for (auto i = errorSummaryMap.begin();
210  i != end; ++i) {
211  auto const& key = i->first;
212  if (key.severity >= edm::ELerror) {
213  ErrorSummaryEntry e{key.category,key.module,key.severity};
214  e.count = i->second.value().load(std::memory_order_acquire);
215  v.push_back(e);
216  }
217  }
218  std::sort(v.begin(),v.end());
219  return v;
220  }
221 
222 } // end namespace edm
223 
bool operator<(DetSet< T > const &x, DetSet< T > const &y)
Definition: DetSet.h:90
int i
Definition: DBlmapReader.cc:9
ELseverityLevel severity
Definition: ELextendedID.h:35
bool EnableLoggedErrorsSummary()
static MessageDrop * instance()
Definition: MessageDrop.cc:60
void operator()(ErrorObj *errorObjPtr)
void clearLoggedErrorsSummary(unsigned int iStreamID)
void setMaxLoggedErrorsSummaryIndicies(unsigned int iMax)
ELslProxy< ELwarningGen > const ELwarning
bool FreshErrorsExist(unsigned int iStreamID)
bool DisableLoggedErrorsSummary()
virtual void setContext(const ELstring &context)
Definition: ErrorObj.cc:191
const ELextendedID & xid() const
Definition: ErrorObj.cc:147
unsigned int streamID
Definition: MessageDrop.h:103
ELslProxy< ELerrorGen > const ELerror
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
#define end
Definition: vmac.h:37
std::string moduleContext()
Definition: MessageDrop.cc:209
std::vector< ErrorSummaryEntry > LoggedErrorsOnlySummary(unsigned int iStreamID)
const int drop
static std::atomic< bool > errorSummaryIsBeingKept
static void MLqLOG(ErrorObj *p)
list key
Definition: combine.py:13
std::vector< ErrorSummaryEntry > LoggedErrorsSummary(unsigned int iStreamID)
static std::vector< tbb::concurrent_unordered_map< ErrorSummaryMapKey, AtomicUnsignedInt, ErrorSummaryMapKey::key_hash > > errorSummaryMaps
std::string runEvent
Definition: MessageDrop.h:102
std::string ELstring
Definition: ELstring.h:26
Definition: vlib.h:208
virtual void setModule(const ELstring &module)
Definition: ErrorObj.cc:189