CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EPStates.cc
Go to the documentation of this file.
1 
4 
5 #include <cassert>
6 #include <exception>
7 #include <sstream>
8 #include <string>
9 
10 namespace statemachine {
11  namespace {
12  edm::RunNumber_t const INVALID_RUN_NUMBER = 0;
13  edm::LuminosityBlockNumber_t const INVALID_LUMI = 0;
14  Run const INVALID_RUN(edm::ProcessHistoryID(), INVALID_RUN_NUMBER);
15  HandleLumis::LumiID const InvalidLumiID = HandleLumis::LumiID(edm::ProcessHistoryID(), INVALID_RUN_NUMBER, INVALID_LUMI);
16  }
17 
19  processHistoryID_(phid),
20  runNumber_(runNumber) {
21  }
22 
24 
27  EmptyRunLumiMode emptyRunLumiMode) :
28  ep_(ep),
29  fileMode_(fileMode),
30  emptyRunLumiMode_(emptyRunLumiMode) {
31  }
32 
33  edm::IEventProcessor& Machine::ep() const { return *ep_; }
34  FileMode Machine::fileMode() const { return fileMode_; }
36 
39  }
40 
42  if(ep_->alreadyHandlingException()) return;
44  }
45 
48  ep_->rewindInput();
49  }
50 
51  Starting::Starting(my_context ctx) : my_base(ctx) { }
52 
54 
55  HandleFiles::HandleFiles(my_context ctx) :
56  my_base(ctx),
57  ep_(context<Machine>().ep()),
58  exitCalled_(false) { }
59 
61  if(ep_.alreadyHandlingException()) return;
62  exitCalled_ = true;
63  closeFiles(false);
64  }
65 
67  if(!exitCalled_) {
68  try {
69  closeFiles(true);
70  }
71  catch(...) {
72  std::string message("Another exception was caught while trying to clean up files after the primary fatal exception.");
74  }
75  }
76  }
77 
78  void HandleFiles::closeFiles(bool cleaningUpAfterException) {
80  ep_.closeInputFile(cleaningUpAfterException);
82  }
83 
86  ep_.closeInputFile(false);
87 
88  ep_.readFile();
90  }
91 
93  if(context<Machine>().fileMode() == NOMERGE) return true;
94  return ep_.shouldWeCloseOutput();
95  }
96 
97  EndingLoop::EndingLoop(my_context ctx) :
98  my_base(ctx),
99  ep_(context<Machine>().ep()) {
100  if(ep_.alreadyHandlingException() || ep_.endOfLoop()) post_event(Stop());
101  else post_event(Restart());
102  }
103 
105 
107  return terminate();
108  }
109 
110  Error::Error(my_context ctx) :
111  my_base(ctx),
112  ep_(context<Machine>().ep()) {
113  post_event(Stop());
114  ep_.doErrorStuff();
115  }
116 
118 
119  class HandleNewInputFile1;
121 
122  FirstFile::FirstFile(my_context ctx) :
123  my_base(ctx),
124  ep_(context<Machine>().ep()) {
125  openFiles();
126  }
127 
129 
131  if(context<HandleFiles>().shouldWeCloseOutput()) {
132  return transit<NewInputAndOutputFiles>();
133  } else {
134  return transit<HandleNewInputFile1>();
135  }
136  }
137 
139  ep_.readFile();
141 
143  }
144 
146  my_base(ctx) {
147  context<HandleFiles>().goToNewInputFile();
148  }
149 
151 
153  if(context<HandleFiles>().shouldWeCloseOutput()) {
154  return transit<NewInputAndOutputFiles>();
155  } else {
156  return transit<HandleNewInputFile1>();
157  }
158  }
159 
161  my_base(ctx),
162  ep_(context<Machine>().ep()) {
164  }
165 
167 
169  if(context<HandleFiles>().shouldWeCloseOutput()) {
170  return transit<NewInputAndOutputFiles>();
171  } else {
172  return transit<HandleNewInputFile1>();
173  }
174  }
175 
178  ep_.closeInputFile(false);
179 
181 
182  ep_.readFile();
184 
186  }
187 
188  HandleRuns::HandleRuns(my_context ctx) :
189  my_base(ctx),
190  ep_(context<Machine>().ep()),
191  exitCalled_(false),
192  beginRunCalled_(false),
193  currentRun_(INVALID_RUN),
194  runException_(false) { }
195 
197  if(ep_.alreadyHandlingException()) return;
198  exitCalled_ = true;
199  finalizeRun(false);
200  }
201 
203  if(!exitCalled_) {
204  try {
205  finalizeRun(true);
206  }
207  catch(...) {
208  std::string message("Another exception was caught while trying to clean up runs after the primary fatal exception.");
209  ep_.setExceptionMessageRuns(message);
210  }
211  }
212  }
213 
215  Run const& HandleRuns::currentRun() const { return currentRun_; }
216  bool HandleRuns::runException() const { return runException_; }
217 
219 
220  runException_ = true;
221  currentRun_ = ep_.readRun();
222  runException_ = false;
223 
224  if(context<Machine>().emptyRunLumiMode() != doNotHandleEmptyRunsAndLumis) {
225  beginRun(currentRun());
226  }
227  }
228 
229  void HandleRuns::beginRun(Run const& run) {
230  beginRunCalled_ = true;
231 
232  runException_ = true;
233  ep_.beginRun(run);
234  runException_ = false;
235  }
236 
237  void HandleRuns::endRun(Run const& run, bool cleaningUpAfterException) {
238  beginRunCalled_ = false;
239 
240  runException_ = true;
241  ep_.endRun(run, cleaningUpAfterException);
242  runException_ = false;
243  }
244 
246  finalizeRun(false);
247  }
248 
249  void HandleRuns::finalizeRun(bool cleaningUpAfterException) {
250 
251  if(runException_) return;
252  runException_ = true;
253 
254  if(beginRunCalled_) endRun(currentRun(), cleaningUpAfterException);
257  currentRun_ = INVALID_RUN;
258  runException_ = false;
259  }
260 
263  }
264 
265  NewRun::NewRun(my_context ctx) :
266  my_base(ctx) {
267  assert(context<HandleRuns>().currentRun() == INVALID_RUN);
268  context<HandleRuns>().setupCurrentRun();
269 
270  // Here we assume that the input source or event processor
271  // will throw if we fail to get a valid run. Therefore
272  // we should not ever fail this assert.
273  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
274  }
275 
277 
279  if(run == context<HandleRuns>().currentRun()) {
280  return transit<ContinueRun1>();
281  }
282  context<HandleRuns>().finalizeRun(false);
283  return transit<NewRun>();
284  }
285 
287  if(!context<HandleFiles>().shouldWeCloseOutput()) {
288  return transit<HandleNewInputFile2>();
289  }
290  return forward_event();
291  }
292 
294  my_base(ctx) {
295  context<HandleFiles>().goToNewInputFile();
296  checkInvariant();
297  }
298 
300  checkInvariant();
301  }
302 
304  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
305  return true;
306  }
307 
309  checkInvariant();
310 
311  if(context<HandleRuns>().currentRun() != run) {
312  return transit<NewRun, HandleRuns, Run>(&HandleRuns::finalizeRun, run);
313  } else {
314  return transit<ContinueRun1>();
315  }
316  }
317 
319  checkInvariant();
320  if(!context<HandleFiles>().shouldWeCloseOutput()) {
321  return transit<HandleNewInputFile2>();
322  }
323  return forward_event();
324  }
325 
326  ContinueRun1::ContinueRun1(my_context ctx) :
327  my_base(ctx),
328  ep_(context<Machine>().ep()) {
330  checkInvariant();
331  }
332 
334  checkInvariant();
335  }
336 
338  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
339  return true;
340  }
341 
343  checkInvariant();
344  if(context<HandleRuns>().currentRun() != run) {
345  return transit<NewRun, HandleRuns, Run>(&HandleRuns::finalizeRun, run);
346  } else {
347  return transit<ContinueRun1>();
348  }
349  }
350 
352  checkInvariant();
353  if(!context<HandleFiles>().shouldWeCloseOutput()) {
354  return transit<HandleNewInputFile2>();
355  }
356  return forward_event();
357  }
358 
360  processHistoryID_(phid),
361  run_(run),
362  lumi_(lumi) {
363  }
364 
365  HandleLumis::HandleLumis(my_context ctx) :
366  my_base(ctx),
367  ep_(context<Machine>().ep()),
370  currentLumi_(InvalidLumiID),
372  checkInvariant();
373  }
374 
376  if(ep_.alreadyHandlingException()) return;
377  exitCalled_ = true;
378  checkInvariant();
379  if(!lumiException_ && !context<HandleRuns>().runException()) {
380  finalizeLumi(false);
381  }
382  }
383 
385  if(!exitCalled_) {
386  try {
387  checkInvariant();
388  if(!lumiException_ && !context<HandleRuns>().runException()) {
389  finalizeLumi(true);
390  }
391  }
392  catch(...) {
393  std::string message("Another exception was caught while trying to clean up lumis after the primary fatal exception.");
394  ep_.setExceptionMessageLumis(message);
395  }
396  }
397  }
398 
400  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
401  return true;
402  }
403 
405 
407 
409 
410  Run const& run = context<HandleRuns>().currentRun();
411  assert(run != INVALID_RUN);
412  lumiException_ = true;
414 
415  if(context<Machine>().emptyRunLumiMode() == handleEmptyRunsAndLumis) {
416  assert(context<HandleRuns>().beginRunCalled());
417  ep_.beginLumi(currentLumi().processHistoryID(), currentLumi().run(), currentLumi().lumi());
418  }
419 
420  lumiException_ = false;
421 
422  currentLumiEmpty_ = true;
423  }
424 
425  void HandleLumis::finalizeLumi(bool cleaningUpAfterException) {
426 
427  lumiException_ = true;
428 
429  if(!currentLumiEmpty_ ||
430  context<Machine>().emptyRunLumiMode() == handleEmptyRunsAndLumis) {
431  ep_.endLumi(currentLumi().processHistoryID(), currentLumi().run(), currentLumi().lumi(), cleaningUpAfterException);
432  }
433 
434  ep_.writeLumi(currentLumi().processHistoryID(), currentLumi().run(), currentLumi().lumi());
435  ep_.deleteLumiFromCache(currentLumi().processHistoryID(), currentLumi().run(), currentLumi().lumi());
436  currentLumi_ = InvalidLumiID;
437 
438  lumiException_ = false;
439  }
440 
442  if(currentLumiEmpty_) {
443 
444  if(context<Machine>().emptyRunLumiMode() != handleEmptyRunsAndLumis) {
445  lumiException_ = true;
446  ep_.beginLumi(currentLumi().processHistoryID(), currentLumi().run(), currentLumi().lumi());
447  lumiException_ = false;
448  }
449  currentLumiEmpty_ = false;
450  }
451  }
452 
453  FirstLumi::FirstLumi(my_context ctx) :
454  my_base(ctx) {
455  context<HandleLumis>().setupCurrentLumi();
456  checkInvariant();
457  }
458 
460  checkInvariant();
461  }
462 
464  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
465  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
466  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
467  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
468  assert(context<HandleLumis>().currentLumiEmpty() == true);
469  return true;
470  }
471 
473  if(lumi.id() == context<HandleLumis>().currentLumi().lumi()) {
474  return transit<ContinueLumi>();
475  }
476  return transit<AnotherLumi>();
477  }
478 
480  checkInvariant();
481  if(!context<HandleFiles>().shouldWeCloseOutput()) {
482  return transit<HandleNewInputFile3>();
483  }
484  return forward_event();
485  }
486 
487  AnotherLumi::AnotherLumi(my_context ctx) :
488  my_base(ctx) {
489  context<HandleLumis>().finalizeLumi(false);
490  context<HandleLumis>().setupCurrentLumi();
491  checkInvariant();
492  }
493 
495  checkInvariant();
496  }
497 
499  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
500  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
501  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
502  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
503  assert(context<HandleLumis>().currentLumiEmpty() == true);
504  return true;
505  }
506 
508  if(lumi.id() == context<HandleLumis>().currentLumi().lumi()) {
509  return transit<ContinueLumi>();
510  }
511  return transit<AnotherLumi>();
512  }
513 
515  checkInvariant();
516  if(!context<HandleFiles>().shouldWeCloseOutput()) {
517  return transit<HandleNewInputFile3>();
518  }
519  return forward_event();
520  }
521 
522  HandleEvent::HandleEvent(my_context ctx) :
523  my_base(ctx),
524  ep_(context<Machine>().ep()) {
526  checkInvariant();
527  }
528 
530  checkInvariant();
531  }
532 
534  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
535  assert(context<HandleRuns>().beginRunCalled());
536  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
537  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
538  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
539  assert(context<HandleLumis>().currentLumiEmpty() == false);
540  return true;
541  }
542 
544  checkInvariant();
545  if(!context<HandleFiles>().shouldWeCloseOutput()) {
546  return transit<HandleNewInputFile3>();
547  }
548  return forward_event();
549  }
550 
552  markNonEmpty();
554  if(ep_.shouldWeStop()) post_event(Stop());
555  }
556 
558  context<HandleRuns>().beginRunIfNotDoneAlready();
559  context<HandleLumis>().markLumiNonEmpty();
560  }
561 
562 
564  my_base(ctx) {
565  context<HandleFiles>().goToNewInputFile();
566  checkInvariant();
567  }
568 
570  checkInvariant();
571  }
572 
574  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
575  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
576  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
577  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
578  return true;
579  }
580 
582  checkInvariant();
583 
584  if(context<HandleRuns>().currentRun() == run) {
585  return transit<ContinueRun2>();
586  }
587  return forward_event();
588  }
589 
591  checkInvariant();
592  if(!context<HandleFiles>().shouldWeCloseOutput()) {
593  return transit<HandleNewInputFile3>();
594  }
595  return forward_event();
596  }
597 
598  ContinueRun2::ContinueRun2(my_context ctx) :
599  my_base(ctx),
600  ep_(context<Machine>().ep()) {
602  checkInvariant();
603  }
604 
606  checkInvariant();
607  }
608 
610  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
611  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
612  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
613  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
614  return true;
615  }
616 
618  checkInvariant();
619  if(context<HandleRuns>().currentRun() != run) {
620  return forward_event();
621  } else {
622  return transit<ContinueRun2>();
623  }
624  }
625 
627  checkInvariant();
628 
629  if(context<HandleLumis>().currentLumi().lumi() != lumi.id()) {
630  return transit<AnotherLumi>();
631  } else {
632  return transit<ContinueLumi>();
633  }
634  }
635 
637  checkInvariant();
638  if(!context<HandleFiles>().shouldWeCloseOutput()) {
639  return transit<HandleNewInputFile3>();
640  }
641  return forward_event();
642  }
643 
644  ContinueLumi::ContinueLumi(my_context ctx) :
645  my_base(ctx),
646  ep_(context<Machine>().ep()) {
648  checkInvariant();
649  }
650 
652  checkInvariant();
653  }
654 
656  assert(context<HandleRuns>().currentRun() != INVALID_RUN);
657  assert(context<HandleLumis>().currentLumi().processHistoryID() == context<HandleRuns>().currentRun().processHistoryID());
658  assert(context<HandleLumis>().currentLumi().run() == context<HandleRuns>().currentRun().runNumber());
659  assert(context<HandleLumis>().currentLumi().lumi() != INVALID_LUMI);
660  return true;
661  }
662 
664  checkInvariant();
665  if(context<HandleLumis>().currentLumi().lumi() != lumi.id()) {
666  return transit<AnotherLumi>();
667  } else {
668  return transit<ContinueLumi>();
669  }
670  }
671 
673  checkInvariant();
674  if(!context<HandleFiles>().shouldWeCloseOutput()) {
675  return transit<HandleNewInputFile3>();
676  }
677  return forward_event();
678  }
679 }
static const char runNumber_[]
HandleEvent(my_context ctx)
Definition: EPStates.cc:522
sc::result react(File const &file)
Definition: EPStates.cc:130
edm::IEventProcessor & ep_
Definition: EPStates.h:343
FirstFile(my_context ctx)
Definition: EPStates.cc:122
edm::IEventProcessor * ep_
Definition: EPStates.h:109
virtual void endRun(statemachine::Run const &run, bool cleaningUpAfterException)=0
void endRun(Run const &run, bool cleaningUpAfterException)
Definition: EPStates.cc:237
HandleFiles(my_context ctx)
Definition: EPStates.cc:55
Starting(my_context ctx)
Definition: EPStates.cc:51
HandleLumis(my_context ctx)
Definition: EPStates.cc:365
virtual void setExceptionMessageFiles(std::string &message)=0
HandleNewInputFile3(my_context ctx)
Definition: EPStates.cc:563
edm::IEventProcessor & ep_
Definition: EPStates.h:179
bool currentLumiEmpty() const
Definition: EPStates.cc:406
edm::IEventProcessor & ep_
Definition: EPStates.h:453
virtual void beginLumi(ProcessHistoryID const &phid, RunNumber_t run, LuminosityBlockNumber_t lumi)=0
FileMode fileMode() const
Definition: EPStates.cc:34
tuple lumi
Definition: fjr2json.py:35
assert(m_qm.get())
edm::IEventProcessor & ep_
Definition: EPStates.h:435
sc::result react(File const &file)
Definition: EPStates.cc:543
sc::result react(File const &file)
Definition: EPStates.cc:168
virtual bool shouldWeStop() const =0
sc::result react(Lumi const &lumi)
Definition: EPStates.cc:663
ContinueLumi(my_context ctx)
Definition: EPStates.cc:644
void closeFiles(bool cleaningUpAfterException)
Definition: EPStates.cc:78
edm::IEventProcessor & ep_
Definition: EPStates.h:154
virtual void writeLumi(ProcessHistoryID const &phid, RunNumber_t run, LuminosityBlockNumber_t lumi)=0
virtual void openOutputFiles()=0
virtual void readAndProcessEvent()=0
sc::result react(Run const &run)
Definition: EPStates.cc:308
unsigned int LuminosityBlockNumber_t
virtual void setExceptionMessageLumis(std::string &message)=0
virtual int readLuminosityBlock()=0
virtual void rewindInput()=0
edm::IEventProcessor & ep_
Definition: EPStates.h:309
void startingNewLoop(File const &file)
Definition: EPStates.cc:37
virtual void startingNewLoop()=0
FirstLumi(my_context ctx)
Definition: EPStates.cc:453
EmptyRunLumiMode emptyRunLumiMode_
Definition: EPStates.h:111
virtual statemachine::Run readAndMergeRun()=0
edm::LuminosityBlockNumber_t id() const
Definition: EPStates.h:69
virtual void readFile()=0
edm::IEventProcessor & ep() const
Definition: EPStates.cc:33
bool beginRunCalled() const
Definition: EPStates.cc:214
HandleRuns(my_context ctx)
Definition: EPStates.cc:188
edm::IEventProcessor & ep_
Definition: EPStates.h:253
EndingLoop(my_context ctx)
Definition: EPStates.cc:97
virtual void endLumi(ProcessHistoryID const &phid, RunNumber_t run, LuminosityBlockNumber_t lumi, bool cleaningUpAfterException)=0
virtual void deleteRunFromCache(statemachine::Run const &run)=0
ContinueRun2(my_context ctx)
Definition: EPStates.cc:598
tuple result
Definition: query.py:137
LumiID const & currentLumi() const
Definition: EPStates.cc:404
HandleNewInputFile1(my_context ctx)
Definition: EPStates.cc:145
edm::IEventProcessor & ep_
Definition: EPStates.h:229
virtual bool shouldWeCloseOutput() const =0
sc::result react(Run const &run)
Definition: EPStates.cc:342
virtual void closeOutputFiles()=0
Run const & currentRun() const
Definition: EPStates.cc:215
ContinueRun1(my_context ctx)
Definition: EPStates.cc:326
edm::IEventProcessor & ep_
Definition: EPStates.h:401
edm::IEventProcessor & ep_
Definition: EPStates.h:197
AnotherLumi(my_context ctx)
Definition: EPStates.cc:487
sc::result react(Lumi const &lumi)
Definition: EPStates.cc:507
virtual void respondToOpenInputFile()=0
virtual void respondToCloseInputFile()=0
void finalizeLumi(bool cleaningUpAfterException)
Definition: EPStates.cc:425
void finalizeRun(Run const &)
Definition: EPStates.cc:245
NewInputAndOutputFiles(my_context ctx)
Definition: EPStates.cc:160
Machine(edm::IEventProcessor *ep, FileMode fileMode, EmptyRunLumiMode emptyRunLumiMode)
Definition: EPStates.cc:25
void rewindAndPrepareForNextLoop(Restart const &restart)
Definition: EPStates.cc:46
NewRun(my_context ctx)
Definition: EPStates.cc:265
sc::result react(Run const &run)
Definition: EPStates.cc:581
Run(edm::ProcessHistoryID const &phid, edm::RunNumber_t runNumber)
Definition: EPStates.cc:18
sc::result react(Lumi const &lumi)
Definition: EPStates.cc:472
sc::result react(Stop const &)
Definition: EPStates.cc:106
virtual bool alreadyHandlingException() const =0
virtual statemachine::Run readRun()=0
HandleNewInputFile2(my_context ctx)
Definition: EPStates.cc:293
edm::IEventProcessor & ep_
Definition: EPStates.h:169
virtual void setExceptionMessageRuns(std::string &message)=0
virtual int readAndMergeLumi()=0
edm::RunNumber_t runNumber() const
Definition: EPStates.h:49
void beginRun(Run const &run)
Definition: EPStates.cc:229
Lumi(edm::LuminosityBlockNumber_t id)
Definition: EPStates.cc:23
virtual bool endOfLoop()=0
edm::ProcessHistoryID const & processHistoryID() const
Definition: EPStates.h:48
virtual void closeInputFile(bool cleaningUpAfterException)=0
Error(my_context ctx)
Definition: EPStates.cc:110
unsigned int RunNumber_t
sc::result react(Run const &run)
Definition: EPStates.cc:278
virtual void doErrorStuff()=0
LumiID(edm::ProcessHistoryID const &phid, edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi)
Definition: EPStates.cc:359
virtual void beginRun(statemachine::Run const &run)=0
volatile std::atomic< bool > shutdown_flag false
sc::result react(Run const &run)
Definition: EPStates.cc:617
EmptyRunLumiMode emptyRunLumiMode() const
Definition: EPStates.cc:35
sc::result react(File const &file)
Definition: EPStates.cc:152
bool runException() const
Definition: EPStates.cc:216
virtual void deleteLumiFromCache(ProcessHistoryID const &phid, RunNumber_t run, LuminosityBlockNumber_t lumi)=0
virtual void writeRun(statemachine::Run const &run)=0
virtual void prepareForNextLoop()=0