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