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