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