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