00001 #ifndef FWCore_Framework_Path_h
00002 #define FWCore_Framework_Path_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "FWCore/Framework/interface/CurrentProcessingContext.h"
00015 #include "FWCore/Framework/src/WorkerInPath.h"
00016 #include "FWCore/Framework/src/Worker.h"
00017 #include "DataFormats/Common/interface/HLTenums.h"
00018 #include "DataFormats/Common/interface/TriggerResults.h"
00019 #include "FWCore/Utilities/interface/BranchType.h"
00020 #include "FWCore/Utilities/interface/Exception.h"
00021 #include "FWCore/Utilities/interface/ConvertException.h"
00022
00023 #include "boost/shared_ptr.hpp"
00024
00025 #include <string>
00026 #include <vector>
00027 #include <exception>
00028 #include <sstream>
00029
00030 #include "FWCore/Framework/src/RunStopwatch.h"
00031
00032 namespace edm {
00033
00034 class Path {
00035 public:
00036 typedef hlt::HLTState State;
00037
00038 typedef std::vector<WorkerInPath> WorkersInPath;
00039 typedef WorkersInPath::size_type size_type;
00040 typedef boost::shared_ptr<HLTGlobalStatus> TrigResPtr;
00041
00042 Path(int bitpos, std::string const& path_name,
00043 WorkersInPath const& workers,
00044 TrigResPtr trptr,
00045 ActionTable const& actions,
00046 boost::shared_ptr<ActivityRegistry> reg,
00047 bool isEndPath);
00048
00049 template <typename T>
00050 void processOneOccurrence(typename T::MyPrincipal&, EventSetup const&);
00051
00052 int bitPosition() const { return bitpos_; }
00053 std::string const& name() const { return name_; }
00054
00055 std::pair<double, double> timeCpuReal() const {
00056 if(stopwatch_) {
00057 return std::pair<double, double>(stopwatch_->cpuTime(), stopwatch_->realTime());
00058 }
00059 return std::pair<double, double>(0., 0.);
00060 }
00061
00062 std::pair<double, double> timeCpuReal(unsigned int const i) const {
00063 return workers_.at(i).timeCpuReal();
00064 }
00065
00066 void clearCounters();
00067
00068 int timesRun() const { return timesRun_; }
00069 int timesPassed() const { return timesPassed_; }
00070 int timesFailed() const { return timesFailed_; }
00071 int timesExcept() const { return timesExcept_; }
00072
00073 State state() const { return state_; }
00074
00075 size_type size() const { return workers_.size(); }
00076 int timesVisited(size_type i) const { return workers_.at(i).timesVisited(); }
00077 int timesPassed (size_type i) const { return workers_.at(i).timesPassed() ; }
00078 int timesFailed (size_type i) const { return workers_.at(i).timesFailed() ; }
00079 int timesExcept (size_type i) const { return workers_.at(i).timesExcept() ; }
00080 Worker const* getWorker(size_type i) const { return workers_.at(i).getWorker(); }
00081
00082 void useStopwatch();
00083 private:
00084 RunStopwatch::StopwatchPointer stopwatch_;
00085 int timesRun_;
00086 int timesPassed_;
00087 int timesFailed_;
00088 int timesExcept_;
00089
00090 State state_;
00091
00092 int bitpos_;
00093 std::string name_;
00094 TrigResPtr trptr_;
00095 boost::shared_ptr<ActivityRegistry> actReg_;
00096 ActionTable const* act_table_;
00097
00098 WorkersInPath workers_;
00099
00100 bool isEndPath_;
00101
00102
00103
00104 bool handleWorkerFailure(cms::Exception & e,
00105 int nwrwue,
00106 bool isEvent,
00107 bool begin,
00108 BranchType branchType,
00109 CurrentProcessingContext const& cpc,
00110 std::string const& id);
00111 static void exceptionContext(cms::Exception & ex,
00112 bool isEvent,
00113 bool begin,
00114 BranchType branchType,
00115 CurrentProcessingContext const& cpc,
00116 std::string const& id);
00117 void recordStatus(int nwrwue, bool isEvent);
00118 void updateCounters(bool succeed, bool isEvent);
00119 };
00120
00121 namespace {
00122 template <typename T>
00123 class PathSignalSentry {
00124 public:
00125 PathSignalSentry(ActivityRegistry *a,
00126 std::string const& name,
00127 int const& nwrwue,
00128 hlt::HLTState const& state) :
00129 a_(a), name_(name), nwrwue_(nwrwue), state_(state) {
00130 if (a_) T::prePathSignal(a_, name_);
00131 }
00132 ~PathSignalSentry() {
00133 HLTPathStatus status(state_, nwrwue_);
00134 if(a_) T::postPathSignal(a_, name_, status);
00135 }
00136 private:
00137 ActivityRegistry* a_;
00138 std::string const& name_;
00139 int const& nwrwue_;
00140 hlt::HLTState const& state_;
00141 };
00142 }
00143
00144 template <typename T>
00145 void Path::processOneOccurrence(typename T::MyPrincipal& ep, EventSetup const& es) {
00146
00147
00148
00149 int nwrwue = -1;
00150 PathSignalSentry<T> signaler(actReg_.get(), name_, nwrwue, state_);
00151
00152
00153 RunStopwatch stopwatch(T::isEvent_ ? stopwatch_ : RunStopwatch::StopwatchPointer());
00154
00155 if (T::isEvent_) {
00156 ++timesRun_;
00157 }
00158 state_ = hlt::Ready;
00159
00160
00161 bool should_continue = true;
00162 CurrentProcessingContext cpc(&name_, bitPosition(), isEndPath_);
00163
00164 WorkersInPath::size_type idx = 0;
00165
00166
00167 for (WorkersInPath::iterator i = workers_.begin(), end = workers_.end();
00168 i != end && should_continue;
00169 ++i, ++idx) {
00170 ++nwrwue;
00171 assert (static_cast<int>(idx) == nwrwue);
00172 try {
00173 try {
00174 cpc.activate(idx, i->getWorker()->descPtr());
00175 should_continue = i->runWorker<T>(ep, es, &cpc);
00176 }
00177 catch (cms::Exception& e) { throw; }
00178 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00179 catch (std::exception& e) { convertException::stdToEDM(e); }
00180 catch(std::string& s) { convertException::stringToEDM(s); }
00181 catch(char const* c) { convertException::charPtrToEDM(c); }
00182 catch (...) { convertException::unknownToEDM(); }
00183 }
00184 catch(cms::Exception& ex) {
00185
00186 std::ostringstream ost;
00187 ost << ep.id();
00188 should_continue = handleWorkerFailure(ex, nwrwue, T::isEvent_, T::begin_, T::branchType_, cpc, ost.str());
00189 }
00190 }
00191 updateCounters(should_continue, T::isEvent_);
00192 recordStatus(nwrwue, T::isEvent_);
00193 }
00194
00195 }
00196
00197 #endif