1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
// -*- C++ -*-
//
// Package: Framework
// Class : SignallingProductRegistryFiller
//
// Implementation:
// <Notes on implementation>
//
// Original Author: Chris Jones
// Created: Fri Sep 23 16:52:50 CEST 2005
//
// system include files
// user include files
#include "FWCore/Framework/interface/SignallingProductRegistryFiller.h"
#include "FWCore/Utilities/interface/Exception.h"
using namespace edm;
//
// member functions
//
namespace {
struct StackGuard {
StackGuard(std::string const& iTypeName, std::map<std::string, unsigned int>& ioStack, bool iFromListener)
: numType_(++ioStack[iTypeName]), itr_(ioStack.find(iTypeName)), fromListener_(iFromListener) {
if (iFromListener) {
++(itr_->second);
}
}
~StackGuard() {
--(itr_->second);
if (fromListener_) {
--(itr_->second);
}
}
unsigned int numType_;
std::map<std::string, unsigned int>::iterator itr_;
bool fromListener_;
};
} // namespace
void SignallingProductRegistryFiller::addCalled(ProductDescription const& iProd, bool iFromListener) {
// Call only for present branches (part of avoiding adding type information for dropped branches)
if (iProd.dropped())
return;
StackGuard guard(iProd.className(), typeAddedStack_, iFromListener);
if (guard.numType_ > 2) {
throw cms::Exception("CircularReference")
<< "Attempted to register the production of " << iProd.className() << " from module " << iProd.moduleLabel()
<< " with product instance \"" << iProd.productInstanceName() << "\"\n"
<< "However, this was in reaction to a registration of a production for the same type \n"
<< "from another module who was also listening to product registrations.\n"
<< "This can lead to circular Event::get* calls.\n"
<< "Please reconfigure job so it does not contain both of the modules.";
}
productAddedSignal_(iProd);
}
|