00001 #ifndef Framework_EPStates_h
00002 #define Framework_EPStates_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "DataFormats/Provenance/interface/ProcessHistoryID.h"
00016
00017 #include "boost/statechart/event.hpp"
00018 #include "boost/statechart/state_machine.hpp"
00019 #include <boost/statechart/state.hpp>
00020 #include <boost/statechart/transition.hpp>
00021 #include <boost/mpl/list.hpp>
00022 #include <boost/statechart/custom_reaction.hpp>
00023 #include <vector>
00024
00025 namespace sc = boost::statechart;
00026 namespace mpl = boost::mpl;
00027
00028 namespace edm {
00029 class IEventProcessor;
00030 }
00031
00032 namespace statemachine {
00033
00034 enum FileMode { NOMERGE, FULLMERGE };
00035
00036 enum EmptyRunLumiMode { handleEmptyRunsAndLumis,
00037 handleEmptyRuns,
00038 doNotHandleEmptyRunsAndLumis
00039 };
00040
00041
00042
00043
00044 class Run : public sc::event<Run> {
00045 public:
00046 Run(edm::ProcessHistoryID const& phid, int runNumber);
00047 edm::ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
00048 int runNumber() const { return runNumber_; }
00049
00050 bool operator==(Run const& rh) const {
00051 return (runNumber_ == rh.runNumber()) &&
00052 (processHistoryID_ == rh.processHistoryID());
00053 }
00054
00055 bool operator!=(Run const& rh) const {
00056 return (runNumber_ != rh.runNumber()) ||
00057 (processHistoryID_ != rh.processHistoryID());
00058 }
00059
00060 private:
00061 edm::ProcessHistoryID processHistoryID_;
00062 int runNumber_;
00063 };
00064
00065 class Lumi : public sc::event<Lumi> {
00066 public:
00067 Lumi(int id);
00068 int id() const { return id_; }
00069 private:
00070 int id_;
00071 };
00072
00073
00074
00075 class Event : public sc::event<Event> { };
00076
00077 class File : public sc::event<File> {};
00078 class Stop : public sc::event<Stop> {};
00079 class Restart : public sc::event<Restart> {};
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 class Starting;
00090
00091 class Machine : public sc::state_machine<Machine, Starting>
00092 {
00093 public:
00094 Machine(edm::IEventProcessor* ep,
00095 FileMode fileMode,
00096 EmptyRunLumiMode emptyRunLumiMode);
00097
00098 edm::IEventProcessor& ep() const;
00099 FileMode fileMode() const;
00100 EmptyRunLumiMode emptyRunLumiMode() const;
00101
00102 void startingNewLoop(File const& file);
00103 void startingNewLoop(Stop const& stop);
00104 void rewindAndPrepareForNextLoop(Restart const& restart);
00105
00106 private:
00107
00108 edm::IEventProcessor* ep_;
00109 FileMode fileMode_;
00110 EmptyRunLumiMode emptyRunLumiMode_;
00111 };
00112
00113 class Error;
00114 class HandleFiles;
00115 class EndingLoop;
00116
00117 class Starting : public sc::state<Starting, Machine>
00118 {
00119 public:
00120 Starting(my_context ctx);
00121 ~Starting();
00122
00123 typedef mpl::list<
00124 sc::transition<Event, Error>,
00125 sc::transition<Lumi, Error>,
00126 sc::transition<Run, Error>,
00127 sc::transition<File, HandleFiles, Machine, &Machine::startingNewLoop>,
00128 sc::transition<Stop, EndingLoop, Machine, &Machine::startingNewLoop>,
00129 sc::transition<Restart, Error> > reactions;
00130 };
00131
00132 class FirstFile;
00133
00134 class HandleFiles : public sc::state<HandleFiles, Machine, FirstFile>
00135 {
00136 public:
00137 HandleFiles(my_context ctx);
00138 void exit();
00139 ~HandleFiles();
00140
00141 typedef mpl::list<
00142 sc::transition<Event, Error>,
00143 sc::transition<Lumi, Error>,
00144 sc::transition<Run, Error>,
00145 sc::transition<File, Error>,
00146 sc::transition<Stop, EndingLoop>,
00147 sc::transition<Restart, Error> > reactions;
00148
00149 void closeFiles(bool cleaningUpAfterException);
00150 void goToNewInputFile();
00151 bool shouldWeCloseOutput();
00152 private:
00153 edm::IEventProcessor & ep_;
00154 bool exitCalled_;
00155 };
00156
00157 class EndingLoop : public sc::state<EndingLoop, Machine>
00158 {
00159 public:
00160 EndingLoop(my_context ctx);
00161 ~EndingLoop();
00162 typedef mpl::list<
00163 sc::transition<Restart, Starting, Machine, &Machine::rewindAndPrepareForNextLoop>,
00164 sc::custom_reaction<Stop> > reactions;
00165
00166 sc::result react(Stop const&);
00167 private:
00168 edm::IEventProcessor & ep_;
00169 };
00170
00171 class Error : public sc::state<Error, Machine>
00172 {
00173 public:
00174 Error(my_context ctx);
00175 ~Error();
00176 typedef sc::transition<Stop, EndingLoop> reactions;
00177 private:
00178 edm::IEventProcessor & ep_;
00179 };
00180
00181 class HandleRuns;
00182
00183 class FirstFile : public sc::state<FirstFile, HandleFiles>
00184 {
00185 public:
00186 FirstFile(my_context ctx);
00187 ~FirstFile();
00188
00189 typedef mpl::list<
00190 sc::transition<Run, HandleRuns>,
00191 sc::custom_reaction<File> > reactions;
00192
00193 sc::result react(File const& file);
00194 void openFiles();
00195 private:
00196 edm::IEventProcessor & ep_;
00197 };
00198
00199 class HandleNewInputFile1 : public sc::state<HandleNewInputFile1, HandleFiles>
00200 {
00201 public:
00202 HandleNewInputFile1(my_context ctx);
00203 ~HandleNewInputFile1();
00204
00205 typedef mpl::list<
00206 sc::transition<Run, HandleRuns>,
00207 sc::custom_reaction<File> > reactions;
00208
00209 sc::result react(File const& file);
00210 };
00211
00212 class NewInputAndOutputFiles : public sc::state<NewInputAndOutputFiles, HandleFiles>
00213 {
00214 public:
00215 NewInputAndOutputFiles(my_context ctx);
00216 ~NewInputAndOutputFiles();
00217
00218 typedef mpl::list<
00219 sc::transition<Run, HandleRuns>,
00220 sc::custom_reaction<File> > reactions;
00221
00222 sc::result react(File const& file);
00223
00224 private:
00225
00226 void goToNewInputAndOutputFiles();
00227
00228 edm::IEventProcessor & ep_;
00229 };
00230
00231 class NewRun;
00232
00233 class HandleRuns : public sc::state<HandleRuns, HandleFiles, NewRun>
00234 {
00235 public:
00236 HandleRuns(my_context ctx);
00237 void exit();
00238 ~HandleRuns();
00239
00240 typedef sc::transition<File, NewInputAndOutputFiles> reactions;
00241
00242 bool beginRunCalled() const;
00243 Run const& currentRun() const;
00244 bool runException() const;
00245 void setupCurrentRun();
00246 void beginRun(Run const& run);
00247 void endRun(Run const& run, bool cleaningUpAfterException);
00248 void finalizeRun(Run const&);
00249 void finalizeRun(bool cleaningUpAfterException);
00250 void beginRunIfNotDoneAlready();
00251 private:
00252 edm::IEventProcessor & ep_;
00253 bool exitCalled_;
00254 bool beginRunCalled_;
00255 Run currentRun_;
00256 bool runException_;
00257 };
00258
00259 class HandleLumis;
00260
00261 class NewRun : public sc::state<NewRun, HandleRuns>
00262 {
00263 public:
00264 NewRun(my_context ctx);
00265 ~NewRun();
00266
00267 typedef mpl::list<
00268 sc::transition<Lumi, HandleLumis>,
00269 sc::custom_reaction<Run>,
00270 sc::custom_reaction<File> > reactions;
00271
00272 sc::result react(Run const& run);
00273 sc::result react(File const& file);
00274 };
00275
00276 class ContinueRun1;
00277
00278 class HandleNewInputFile2 : public sc::state<HandleNewInputFile2, HandleRuns>
00279 {
00280 public:
00281 HandleNewInputFile2(my_context ctx);
00282 ~HandleNewInputFile2();
00283 bool checkInvariant();
00284
00285 typedef mpl::list<
00286 sc::custom_reaction<Run>,
00287 sc::custom_reaction<File> > reactions;
00288
00289 sc::result react(Run const& run);
00290 sc::result react(File const& file);
00291 };
00292
00293 class ContinueRun1 : public sc::state<ContinueRun1, HandleRuns>
00294 {
00295 public:
00296 ContinueRun1(my_context ctx);
00297 ~ContinueRun1();
00298 bool checkInvariant();
00299
00300 typedef mpl::list<
00301 sc::custom_reaction<Run>,
00302 sc::custom_reaction<File>,
00303 sc::transition<Lumi, HandleLumis> > reactions;
00304
00305 sc::result react(Run const& run);
00306 sc::result react(File const& file);
00307 private:
00308 edm::IEventProcessor & ep_;
00309 };
00310
00311 class FirstLumi;
00312
00313 class HandleLumis : public sc::state<HandleLumis, HandleRuns, FirstLumi>
00314 {
00315 public:
00316 class LumiID {
00317 public:
00318 LumiID(edm::ProcessHistoryID const& phid, int run, int lumi);
00319 edm::ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
00320 int run() const { return run_; }
00321 int lumi() const { return lumi_; }
00322
00323 private:
00324 edm::ProcessHistoryID processHistoryID_;
00325 int run_;
00326 int lumi_;
00327 };
00328 HandleLumis(my_context ctx);
00329 void exit();
00330 ~HandleLumis();
00331 bool checkInvariant();
00332
00333 LumiID const& currentLumi() const;
00334 bool currentLumiEmpty() const;
00335 void setupCurrentLumi();
00336 void finalizeLumi(bool cleaningUpAfterException);
00337 void markLumiNonEmpty();
00338
00339 typedef sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun> reactions;
00340
00341 private:
00342 edm::IEventProcessor & ep_;
00343 bool exitCalled_;
00344 bool currentLumiEmpty_;
00345 LumiID currentLumi_;
00346 bool lumiException_;
00347 };
00348
00349 class HandleEvent;
00350 class AnotherLumi;
00351
00352 class FirstLumi : public sc::state<FirstLumi, HandleLumis>
00353 {
00354 public:
00355 FirstLumi(my_context ctx);
00356 ~FirstLumi();
00357 bool checkInvariant();
00358
00359 typedef mpl::list<
00360 sc::transition<Event, HandleEvent>,
00361 sc::custom_reaction<Lumi>,
00362 sc::custom_reaction<File> > reactions;
00363
00364 sc::result react(Lumi const& lumi);
00365 sc::result react(File const& file);
00366 };
00367
00368 class AnotherLumi : public sc::state<AnotherLumi, HandleLumis>
00369 {
00370 public:
00371 AnotherLumi(my_context ctx);
00372 ~AnotherLumi();
00373 bool checkInvariant();
00374
00375 typedef mpl::list<
00376 sc::transition<Event, HandleEvent>,
00377 sc::custom_reaction<Lumi>,
00378 sc::custom_reaction<File> > reactions;
00379
00380 sc::result react(Lumi const& lumi);
00381 sc::result react(File const& file);
00382 };
00383
00384 class HandleEvent : public sc::state<HandleEvent, HandleLumis>
00385 {
00386 public:
00387 HandleEvent(my_context ctx);
00388 ~HandleEvent();
00389 bool checkInvariant();
00390
00391 typedef mpl::list<
00392 sc::transition<Event, HandleEvent>,
00393 sc::transition<Lumi, AnotherLumi>,
00394 sc::custom_reaction<File> > reactions;
00395
00396 sc::result react(File const& file);
00397 void readAndProcessEvent();
00398 void markNonEmpty();
00399 private:
00400 edm::IEventProcessor & ep_;
00401 };
00402
00403 class HandleNewInputFile3 : public sc::state<HandleNewInputFile3, HandleLumis>
00404 {
00405 public:
00406 HandleNewInputFile3(my_context ctx);
00407 ~HandleNewInputFile3();
00408 bool checkInvariant();
00409
00410 typedef mpl::list<
00411 sc::custom_reaction<Run>,
00412 sc::custom_reaction<File> > reactions;
00413
00414 sc::result react(Run const& run);
00415 sc::result react(File const& file);
00416 };
00417
00418 class ContinueRun2 : public sc::state<ContinueRun2, HandleLumis>
00419 {
00420 public:
00421 ContinueRun2(my_context ctx);
00422 ~ContinueRun2();
00423 bool checkInvariant();
00424
00425 typedef mpl::list<
00426 sc::custom_reaction<Run>,
00427 sc::custom_reaction<Lumi>,
00428 sc::custom_reaction<File> > reactions;
00429
00430 sc::result react(Run const& run);
00431 sc::result react(Lumi const& lumi);
00432 sc::result react(File const& file);
00433 private:
00434 edm::IEventProcessor & ep_;
00435 };
00436
00437 class ContinueLumi : public sc::state<ContinueLumi, HandleLumis>
00438 {
00439 public:
00440 ContinueLumi(my_context ctx);
00441 ~ContinueLumi();
00442 bool checkInvariant();
00443
00444 typedef mpl::list<
00445 sc::transition<Event, HandleEvent>,
00446 sc::custom_reaction<Lumi>,
00447 sc::custom_reaction<File> > reactions;
00448
00449 sc::result react(Lumi const& lumi);
00450 sc::result react(File const& file);
00451 private:
00452 edm::IEventProcessor & ep_;
00453 };
00454 }
00455
00456 #endif