00001 #include <iostream> 00002 #include <typeinfo> 00003 00004 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00005 #include "FWCore/Utilities/interface/Exception.h" 00006 #include "FWCore/Utilities/interface/EDMException.h" 00007 #include "FWCore/Utilities/interface/FriendlyName.h" 00008 00009 #include "GeneratorInterface/Core/interface/FortranInstance.h" 00010 00011 // implementation for the Fortran callbacks from Pythia6/Herwig6 00012 00013 void gen::upinit_() 00014 { FortranInstance::getInstance<FortranInstance>()->upInit(); } 00015 00016 void gen::upevnt_() 00017 { FortranInstance::getInstance<FortranInstance>()->upEvnt(); } 00018 00019 void gen::upveto_(int *veto) 00020 { *veto = FortranInstance::getInstance<FortranInstance>()->upVeto(); } 00021 00022 // static FortranInstance members; 00023 00024 gen::FortranInstance *gen::FortranInstance::currentInstance = 0; 00025 00026 // FortranInstance methods 00027 00028 gen::FortranInstance::~FortranInstance() 00029 { 00030 if (currentInstance == this) { 00031 edm::LogWarning("ReentrancyProblem") 00032 << edm::friendlyname::friendlyName(typeid(*this).name()) 00033 << " destroyed while it was the " 00034 "current active instance." << std::endl; 00035 currentInstance = 0; 00036 } 00037 } 00038 00039 // FortranInstance current instance tracking 00040 00041 void gen::FortranInstance::enter() 00042 { 00043 // we should add a boost::mutex here if we care about being 00044 // multithread-safe 00045 if (currentInstance && currentInstance != this) 00046 throw edm::Exception(edm::errors::LogicError) 00047 << edm::friendlyname::friendlyName(typeid(*this).name()) 00048 << "::enter() called from a different " 00049 "instance while an instance was already active." 00050 << std::endl; 00051 00052 if (!currentInstance && instanceNesting != 0) 00053 throw edm::Exception(edm::errors::LogicError) 00054 << edm::friendlyname::friendlyName(typeid(*this).name()) 00055 << "::enter() called on an empty " 00056 "instance, but instance counter is nonzero." 00057 << std::endl; 00058 00059 currentInstance = this; 00060 instanceNesting++; 00061 } 00062 00063 void gen::FortranInstance::leave() 00064 { 00065 if (!currentInstance) 00066 throw edm::Exception(edm::errors::LogicError) 00067 << edm::friendlyname::friendlyName(typeid(*this).name()) 00068 << "::leave() called without an " 00069 "active instance." << std::endl; 00070 else if (currentInstance != this) 00071 throw edm::Exception(edm::errors::LogicError) 00072 << edm::friendlyname::friendlyName(typeid(*this).name()) 00073 << "::leave() called from a " 00074 "different instance." << std::endl; 00075 else if (instanceNesting <= 0) 00076 throw edm::Exception(edm::errors::LogicError) 00077 << edm::friendlyname::friendlyName(typeid(*this).name()) 00078 << "::leave() called with a " 00079 "nesting level of zero." << std::endl; 00080 00081 if (--instanceNesting == 0) 00082 currentInstance = 0; 00083 } 00084 00085 void gen::FortranInstance::throwMissingInstance() 00086 { 00087 throw edm::Exception(edm::errors::LogicError) 00088 << "FortranInstance::getInstance() called from " 00089 "a Fortran context, but no current instance " 00090 "has been registered." << std::endl; 00091 } 00092 00093 // Herwig callback stubs 00094 00095 void gen::FortranInstance::upInit() 00096 { 00097 throw cms::Exception("UnimplementedCallback") 00098 << edm::friendlyname::friendlyName(typeid(*this).name()) 00099 << "::upInit() stub called. " 00100 "If user process needs to be generated, please derive " 00101 "and implement the upInit() method." << std::endl; 00102 } 00103 00104 void gen::FortranInstance::upEvnt() 00105 { 00106 throw cms::Exception("UnimplementedCallback") 00107 << edm::friendlyname::friendlyName(typeid(*this).name()) 00108 << "::upEvnt() stub called. " 00109 "If user process needs to be generated, please derive " 00110 "and implement the upEvnt() method." << std::endl; 00111 } 00112 00113 bool gen::FortranInstance::upVeto() 00114 { 00115 return false; 00116 }