Go to the documentation of this file.00001 #ifndef FWCore_Framework_Worker_h
00002 #define FWCore_Framework_Worker_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00025 #include "FWCore/MessageLogger/interface/ExceptionMessages.h"
00026 #include "FWCore/Framework/src/WorkerParams.h"
00027 #include "FWCore/Framework/interface/Actions.h"
00028 #include "FWCore/Framework/interface/CurrentProcessingContext.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00031 #include "FWCore/Utilities/interface/Exception.h"
00032 #include "FWCore/Utilities/interface/ConvertException.h"
00033 #include "FWCore/Utilities/interface/BranchType.h"
00034
00035 #include "boost/shared_ptr.hpp"
00036 #include "boost/utility.hpp"
00037
00038 #include "FWCore/Framework/src/RunStopwatch.h"
00039 #include "FWCore/Framework/interface/Frameworkfwd.h"
00040
00041 #include <sstream>
00042
00043 namespace edm {
00044 class EventPrincipal;
00045 class EarlyDeleteHelper;
00046
00047 class Worker : private boost::noncopyable {
00048 public:
00049 enum State { Ready, Pass, Fail, Exception };
00050
00051 Worker(ModuleDescription const& iMD, WorkerParams const& iWP);
00052 virtual ~Worker();
00053
00054 template <typename T>
00055 bool doWork(typename T::MyPrincipal&, EventSetup const& c,
00056 CurrentProcessingContext const* cpc,
00057 CPUTimer *const timer);
00058 void beginJob() ;
00059 void endJob();
00060 void respondToOpenInputFile(FileBlock const& fb) {implRespondToOpenInputFile(fb);}
00061 void respondToCloseInputFile(FileBlock const& fb) {implRespondToCloseInputFile(fb);}
00062 void respondToOpenOutputFiles(FileBlock const& fb) {implRespondToOpenOutputFiles(fb);}
00063 void respondToCloseOutputFiles(FileBlock const& fb) {implRespondToCloseOutputFiles(fb);}
00064
00065 void preForkReleaseResources() {implPreForkReleaseResources();}
00066 void postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren) {implPostForkReacquireResources(iChildIndex, iNumberOfChildren);}
00067
00068 void reset() { state_ = Ready; }
00069
00070 void pathFinished(EventPrincipal&);
00071 void postDoEvent(EventPrincipal&);
00072
00073 ModuleDescription const& description() const {return md_;}
00074 ModuleDescription const* descPtr() const {return &md_; }
00077 void setActivityRegistry(boost::shared_ptr<ActivityRegistry> areg);
00078
00079 void setEarlyDeleteHelper(EarlyDeleteHelper* iHelper);
00080
00081 std::pair<double, double> timeCpuReal() const {
00082 return std::pair<double, double>(stopwatch_->cpuTime(), stopwatch_->realTime());
00083 }
00084
00085 void clearCounters() {
00086 timesRun_ = timesVisited_ = timesPassed_ = timesFailed_ = timesExcept_ = 0;
00087 }
00088
00089 void useStopwatch();
00090
00091 int timesRun() const { return timesRun_; }
00092 int timesVisited() const { return timesVisited_; }
00093 int timesPassed() const { return timesPassed_; }
00094 int timesFailed() const { return timesFailed_; }
00095 int timesExcept() const { return timesExcept_; }
00096 State state() const { return state_; }
00097
00098 int timesPass() const { return timesPassed(); }
00099
00100 protected:
00101 virtual std::string workerType() const = 0;
00102 virtual bool implDoBegin(EventPrincipal&, EventSetup const& c,
00103 CurrentProcessingContext const* cpc) = 0;
00104 virtual bool implDoEnd(EventPrincipal&, EventSetup const& c,
00105 CurrentProcessingContext const* cpc) = 0;
00106 virtual bool implDoBegin(RunPrincipal& rp, EventSetup const& c,
00107 CurrentProcessingContext const* cpc) = 0;
00108 virtual bool implDoEnd(RunPrincipal& rp, EventSetup const& c,
00109 CurrentProcessingContext const* cpc) = 0;
00110 virtual bool implDoBegin(LuminosityBlockPrincipal& lbp, EventSetup const& c,
00111 CurrentProcessingContext const* cpc) = 0;
00112 virtual bool implDoEnd(LuminosityBlockPrincipal& lbp, EventSetup const& c,
00113 CurrentProcessingContext const* cpc) = 0;
00114 virtual void implBeginJob() = 0;
00115 virtual void implEndJob() = 0;
00116
00117 private:
00118 virtual void implRespondToOpenInputFile(FileBlock const& fb) = 0;
00119 virtual void implRespondToCloseInputFile(FileBlock const& fb) = 0;
00120 virtual void implRespondToOpenOutputFiles(FileBlock const& fb) = 0;
00121 virtual void implRespondToCloseOutputFiles(FileBlock const& fb) = 0;
00122
00123 virtual void implPreForkReleaseResources() = 0;
00124 virtual void implPostForkReacquireResources(unsigned int iChildIndex,
00125 unsigned int iNumberOfChildren) = 0;
00126 RunStopwatch::StopwatchPointer stopwatch_;
00127
00128 int timesRun_;
00129 int timesVisited_;
00130 int timesPassed_;
00131 int timesFailed_;
00132 int timesExcept_;
00133 State state_;
00134
00135 ModuleDescription md_;
00136 ActionTable const* actions_;
00137 boost::shared_ptr<cms::Exception> cached_exception_;
00138
00139 boost::shared_ptr<ActivityRegistry> actReg_;
00140
00141 EarlyDeleteHelper* earlyDeleteHelper_;
00142 };
00143
00144 namespace {
00145 template <typename T>
00146 class ModuleSignalSentry {
00147 public:
00148 ModuleSignalSentry(ActivityRegistry *a, ModuleDescription& md) : a_(a), md_(&md) {
00149 if(a_) T::preModuleSignal(a_, md_);
00150 }
00151 ~ModuleSignalSentry() {
00152 if(a_) T::postModuleSignal(a_, md_);
00153 }
00154 private:
00155 ActivityRegistry* a_;
00156 ModuleDescription* md_;
00157 };
00158
00159 template <typename T>
00160 void exceptionContext(typename T::MyPrincipal const& principal,
00161 cms::Exception& ex,
00162 CurrentProcessingContext const* cpc) {
00163 std::ostringstream ost;
00164 if (T::isEvent_) {
00165 ost << "Calling event method";
00166 }
00167 else if (T::begin_ && T::branchType_ == InRun) {
00168 ost << "Calling beginRun";
00169 }
00170 else if (T::begin_ && T::branchType_ == InLumi) {
00171 ost << "Calling beginLuminosityBlock";
00172 }
00173 else if (!T::begin_ && T::branchType_ == InLumi) {
00174 ost << "Calling endLuminosityBlock";
00175 }
00176 else if (!T::begin_ && T::branchType_ == InRun) {
00177 ost << "Calling endRun";
00178 }
00179 else {
00180
00181 ost << "Calling unknown function";
00182 }
00183 if (cpc && cpc->moduleDescription()) {
00184 ost << " for module " << cpc->moduleDescription()->moduleName() << "/'" << cpc->moduleDescription()->moduleLabel() << "'";
00185 }
00186 ex.addContext(ost.str());
00187 ost.str("");
00188 ost << "Running path '";
00189 if (cpc && cpc->pathName()) {
00190 ost << *cpc->pathName() << "'";
00191 }
00192 else {
00193 ost << "unknown'";
00194 }
00195 ex.addContext(ost.str());
00196 ost.str("");
00197 ost << "Processing ";
00198 ost << principal.id();
00199 ex.addContext(ost.str());
00200 }
00201 }
00202
00203 template <typename T>
00204 bool Worker::doWork(typename T::MyPrincipal& ep,
00205 EventSetup const& es,
00206 CurrentProcessingContext const* cpc,
00207 CPUTimer* const iTimer) {
00208
00209
00210 RunDualStopwatches stopwatch(T::isEvent_ ? stopwatch_ : RunStopwatch::StopwatchPointer(),
00211 iTimer);
00212
00213 if (T::isEvent_) {
00214 ++timesVisited_;
00215 }
00216 bool rc = false;
00217
00218 switch(state_) {
00219 case Ready: break;
00220 case Pass: return true;
00221 case Fail: return false;
00222 case Exception: {
00223 cached_exception_->raise();
00224 }
00225 }
00226
00227 if (T::isEvent_) ++timesRun_;
00228
00229 try {
00230 try {
00231
00232 ModuleSignalSentry<T> cpp(actReg_.get(), md_);
00233 if (T::begin_) {
00234 rc = implDoBegin(ep, es, cpc);
00235 } else {
00236 rc = implDoEnd(ep, es, cpc);
00237 }
00238
00239 if (rc) {
00240 state_ = Pass;
00241 if (T::isEvent_) ++timesPassed_;
00242 } else {
00243 state_ = Fail;
00244 if (T::isEvent_) ++timesFailed_;
00245 }
00246 }
00247 catch (cms::Exception& e) { throw; }
00248 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00249 catch (std::exception& e) { convertException::stdToEDM(e); }
00250 catch(std::string& s) { convertException::stringToEDM(s); }
00251 catch(char const* c) { convertException::charPtrToEDM(c); }
00252 catch (...) { convertException::unknownToEDM(); }
00253 }
00254 catch(cms::Exception& ex) {
00255
00256
00257
00258
00259
00260
00261
00262 actions::ActionCodes action = (T::isEvent_ ? actions_->find(ex.category()) : actions::Rethrow);
00263
00264
00265
00266
00267 if (cpc && cpc->isEndPath()) {
00268 if ((action == actions::SkipEvent && !cpc->isUnscheduled()) ||
00269 action == actions::FailPath) action = actions::IgnoreCompletely;
00270 }
00271 switch(action) {
00272 case actions::IgnoreCompletely:
00273 rc = true;
00274 ++timesPassed_;
00275 state_ = Pass;
00276 exceptionContext<T>(ep, ex, cpc);
00277 edm::printCmsExceptionWarning("IgnoreCompletely", ex);
00278 break;
00279 default:
00280 if (T::isEvent_) ++timesExcept_;
00281 state_ = Exception;
00282 cached_exception_.reset(ex.clone());
00283 cached_exception_->raise();
00284 }
00285 }
00286 return rc;
00287 }
00288 }
00289 #endif