File indexing completed on 2023-03-17 11:03:38
0001 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0002 #include "FWCore/ServiceRegistry/interface/InternalContext.h"
0003 #include "FWCore/ServiceRegistry/interface/PathContext.h"
0004 #include "FWCore/ServiceRegistry/interface/PlaceInPathContext.h"
0005 #include "FWCore/ServiceRegistry/interface/StreamContext.h"
0006 #include "FWCore/ServiceRegistry/interface/GlobalContext.h"
0007 #include "FWCore/Utilities/interface/EDMException.h"
0008 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0009
0010 #include <ostream>
0011
0012 namespace edm {
0013
0014 ModuleCallingContext::ModuleCallingContext(ModuleDescription const* moduleDescription)
0015 : previousModuleOnThread_(nullptr), moduleDescription_(moduleDescription), parent_(), state_(State::kInvalid) {}
0016
0017 ModuleCallingContext::ModuleCallingContext(ModuleDescription const* moduleDescription,
0018 State state,
0019 ParentContext const& parent,
0020 ModuleCallingContext const* previousOnThread)
0021 : previousModuleOnThread_(previousOnThread),
0022 moduleDescription_(moduleDescription),
0023 parent_(parent),
0024 state_(state) {}
0025
0026 void ModuleCallingContext::setContext(State state,
0027 ParentContext const& parent,
0028 ModuleCallingContext const* previousOnThread) {
0029 state_ = state;
0030 parent_ = parent;
0031 previousModuleOnThread_ = previousOnThread;
0032 }
0033
0034 StreamContext const* ModuleCallingContext::getStreamContext() const {
0035 ModuleCallingContext const* mcc = getTopModuleCallingContext();
0036 if (mcc->type() == ParentContext::Type::kPlaceInPath) {
0037 return mcc->placeInPathContext()->pathContext()->streamContext();
0038 } else if (mcc->type() != ParentContext::Type::kStream) {
0039 throw Exception(errors::LogicError)
0040 << "ModuleCallingContext::getStreamContext() called in context not linked to a StreamContext\n";
0041 }
0042 return mcc->streamContext();
0043 }
0044
0045 GlobalContext const* ModuleCallingContext::getGlobalContext() const {
0046 ModuleCallingContext const* mcc = getTopModuleCallingContext();
0047 if (mcc->type() != ParentContext::Type::kGlobal) {
0048 throw Exception(errors::LogicError)
0049 << "ModuleCallingContext::getGlobalContext() called in context not linked to a GlobalContext\n";
0050 }
0051 return mcc->globalContext();
0052 }
0053
0054 ModuleCallingContext const* ModuleCallingContext::getTopModuleCallingContext() const {
0055 ModuleCallingContext const* mcc = this;
0056 while (mcc->type() == ParentContext::Type::kModule) {
0057 mcc = mcc->moduleCallingContext();
0058 }
0059 if (mcc->type() == ParentContext::Type::kInternal) {
0060 mcc = mcc->internalContext()->moduleCallingContext();
0061 }
0062 while (mcc->type() == ParentContext::Type::kModule) {
0063 mcc = mcc->moduleCallingContext();
0064 }
0065 return mcc;
0066 }
0067
0068 unsigned ModuleCallingContext::depth() const {
0069 unsigned depth = 0;
0070 ModuleCallingContext const* mcc = this;
0071 while (mcc->type() == ParentContext::Type::kModule) {
0072 ++depth;
0073 mcc = mcc->moduleCallingContext();
0074 }
0075 if (mcc->type() == ParentContext::Type::kInternal) {
0076 ++depth;
0077 mcc = mcc->internalContext()->moduleCallingContext();
0078 }
0079 while (mcc->type() == ParentContext::Type::kModule) {
0080 ++depth;
0081 mcc = mcc->moduleCallingContext();
0082 }
0083 return depth;
0084 }
0085
0086 void exceptionContext(cms::Exception& ex, ModuleCallingContext const& mcc) {
0087 ModuleCallingContext const* imcc = &mcc;
0088 while ((imcc->type() == ParentContext::Type::kModule) or (imcc->type() == ParentContext::Type::kInternal)) {
0089 std::ostringstream iost;
0090 if (imcc->state() == ModuleCallingContext::State::kPrefetching) {
0091 iost << "Prefetching for module ";
0092 } else {
0093 iost << "Calling method for module ";
0094 }
0095 iost << imcc->moduleDescription()->moduleName() << "/'" << imcc->moduleDescription()->moduleLabel() << "'";
0096
0097 if (imcc->type() == ParentContext::Type::kInternal) {
0098 iost << " (probably inside some kind of mixing module)";
0099 imcc = imcc->internalContext()->moduleCallingContext();
0100 } else {
0101 imcc = imcc->moduleCallingContext();
0102 }
0103 ex.addContext(iost.str());
0104 }
0105 std::ostringstream ost;
0106 if (imcc->state() == ModuleCallingContext::State::kPrefetching) {
0107 ost << "Prefetching for module ";
0108 } else {
0109 ost << "Calling method for module ";
0110 }
0111 ost << imcc->moduleDescription()->moduleName() << "/'" << imcc->moduleDescription()->moduleLabel() << "'";
0112 ex.addContext(ost.str());
0113
0114 if (imcc->type() == ParentContext::Type::kPlaceInPath) {
0115 ost.str("");
0116 ost << "Running path '";
0117 ost << imcc->placeInPathContext()->pathContext()->pathName() << "'";
0118 ex.addContext(ost.str());
0119 auto streamContext = imcc->placeInPathContext()->pathContext()->streamContext();
0120 if (streamContext) {
0121 ost.str("");
0122 edm::exceptionContext(ost, *streamContext);
0123 ex.addContext(ost.str());
0124 }
0125 } else {
0126 if (imcc->type() == ParentContext::Type::kStream) {
0127 ost.str("");
0128 edm::exceptionContext(ost, *(imcc->streamContext()));
0129 ex.addContext(ost.str());
0130 } else if (imcc->type() == ParentContext::Type::kGlobal) {
0131 ost.str("");
0132 edm::exceptionContext(ost, *(imcc->globalContext()));
0133 ex.addContext(ost.str());
0134 }
0135 }
0136 }
0137
0138 std::ostream& operator<<(std::ostream& os, ModuleCallingContext const& mcc) {
0139 os << "ModuleCallingContext state = ";
0140 switch (mcc.state()) {
0141 case ModuleCallingContext::State::kInvalid:
0142 os << "Invalid";
0143 break;
0144 case ModuleCallingContext::State::kPrefetching:
0145 os << "Prefetching";
0146 break;
0147 case ModuleCallingContext::State::kRunning:
0148 os << "Running";
0149 break;
0150 }
0151 os << "\n";
0152 if (mcc.state() == ModuleCallingContext::State::kInvalid) {
0153 return os;
0154 }
0155 if (mcc.moduleDescription()) {
0156 os << " moduleDescription: " << *mcc.moduleDescription() << "\n";
0157 }
0158 os << " " << mcc.parent();
0159 if (mcc.previousModuleOnThread()) {
0160 if (mcc.type() == ParentContext::Type::kModule && mcc.moduleCallingContext() == mcc.previousModuleOnThread()) {
0161 os << " previousModuleOnThread: same as parent module\n";
0162 } else {
0163 os << " previousModuleOnThread: " << *mcc.previousModuleOnThread();
0164 }
0165 }
0166 return os;
0167 }
0168 }