00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "FWCore/Framework/src/SignallingProductRegistry.h"
00018 #include "FWCore/Utilities/interface/Exception.h"
00019
00020 using namespace edm;
00021
00022
00023
00024 namespace {
00025 struct StackGuard {
00026 StackGuard(const std::string& iTypeName, std::map<std::string,unsigned int>& ioStack, bool iFromListener):
00027 numType_(++ioStack[iTypeName]), itr_(ioStack.find(iTypeName)),fromListener_(iFromListener)
00028 { if(iFromListener) {++(itr_->second);} }
00029
00030 ~StackGuard() {
00031 --(itr_->second);
00032 if(fromListener_){
00033 --(itr_->second);
00034 }
00035 }
00036
00037 unsigned int numType_;
00038 std::map<std::string,unsigned int>::iterator itr_;
00039 bool fromListener_;
00040 };
00041 }
00042
00043 void SignallingProductRegistry::addCalled(BranchDescription const& iProd, bool iFromListener)
00044 {
00045 StackGuard guard(iProd.className(), typeAddedStack_, iFromListener);
00046 if(guard.numType_ > 2) {
00047 throw cms::Exception("CircularReference")
00048 <<"Attempted to register the production of "<<iProd.className()
00049 <<" from module "
00050 <<iProd.moduleLabel()
00051 <<" with product instance \""
00052 <<iProd.productInstanceName()
00053 <<"\"\n"
00054 <<"However, this was in reaction to a registration of a production for the same type \n"
00055 <<"from another module who was also listening to product registrations.\n"
00056 <<"This can lead to circular Event::get* calls.\n"
00057 <<"Please reconfigure job so it does not contain both of the modules.";
00058 }
00059 productAddedSignal_(iProd);
00060 }