00001
00002
00003
00004
00005
00006
00007
00009 #include "JobControl/JobCPath.h"
00010 #include <cstring>
00011 #include <vector>
00012 #ifdef SITE_HAS_SIGC
00013 # include "sigc++/class_slot.h"
00014 #endif
00015 #include "MessageService/MsgService.h"
00016 #include "MessageService/MsgFormat.h"
00017 #include "MessageService/MsgTripWire.h"
00018 #include "JobControl/JobCEnv.h"
00019 #include "JobControl/JobCModuleRegistry.h"
00020 #include "JobControl/JobCModuleProxy.h"
00021 #include "JobControl/JobCRecord.h"
00022 #include "JobControl/JobCModule.h"
00023 #include "JobControl/JobCMethod.h"
00024 #include "JobControl/JobCommand.h"
00025 #include "JobControl/JobCInput.h"
00026
00027 using namespace std;
00028
00029 CVSID("$Id: JobCPath.cxx,v 1.65 2007/10/25 17:21:25 bckhouse Exp $");
00030
00031 ClassImp(JobCPath)
00032
00033 class JobCPathConnectionHelper
00034 {
00035
00036
00037
00038 public:
00039 JobCPathConnectionHelper(const JobCPath* p) {
00040 this->BuildConnectionList(p);
00041 this->PreenConnectionList();
00042 }
00043 void BuildConnectionList(const JobCPath* p1) {
00044
00045 fConnectionList.push_back(p1);
00046 for (int i=0; void *v=p1->GetAttached(i); ++i) {
00047 JobCPath *p2 = static_cast<JobCPath*>(v);
00048 this->BuildConnectionList(p2);
00049 }
00050 }
00051 void PreenConnectionList() {
00052
00053 int size = fConnectionList.size();
00054 for (int i=0; i<size-1; ++i) {
00055 for (int j=i+1; j<size; ++j) {
00056 if (fConnectionList[i] == fConnectionList[j]) fConnectionList[i] = 0;
00057 }
00058 }
00059 }
00060 ostream& DoPrint(ostream& os) {
00061
00062 vector<const JobCPath*>::iterator itr(fConnectionList.begin());
00063 vector<const JobCPath*>::iterator itrEnd(fConnectionList.end());
00064 for (; itr!=itrEnd; ++itr) if (*itr) (*itr)->Print(os);
00065 return os;
00066 }
00067 void DoHandleResult(const JobCResult& r) {
00068
00069 vector<const JobCPath*>::iterator itr(fConnectionList.begin());
00070 vector<const JobCPath*>::iterator itrEnd(fConnectionList.end());
00071 for (; itr!=itrEnd; ++itr) {
00072 if (*itr) (*itr)->HandleResult(r);
00073 }
00074 }
00075 void DoBeginJob() {
00076
00077 vector<const JobCPath*>::iterator itr(fConnectionList.begin());
00078 vector<const JobCPath*>::iterator itrEnd(fConnectionList.end());
00079 for (; itr!=itrEnd; ++itr) {
00080 if (*itr) (*itr)->BeginJob();
00081 }
00082 }
00083 void SetRefreshMode(bool m) {
00084
00085 vector<const JobCPath*>::iterator itr(fConnectionList.begin());
00086 vector<const JobCPath*>::iterator itrEnd(fConnectionList.end());
00087 for (; itr!=itrEnd; ++itr) {
00088 if (*itr) (*itr)->SetRefreshMode(m);
00089 }
00090 }
00091 private:
00092 vector<const JobCPath*> fConnectionList;
00093 };
00094
00095
00096
00097 void JobCPath::Print(ostream& os) const
00098 {
00099
00100
00101
00102 os << fName.c_str()
00103 << "("
00104 << fNin << " in "
00105 << fNpass << " out "
00106 << fNfail << " filt.)\n";
00107 int i=0;
00108 MsgFormat i1("%3d");
00109 list<JobCNode*>::const_iterator itrEnd = fNodeList.end();
00110 for (list<JobCNode*>::const_iterator itrJobCNode = fNodeList.begin();
00111 itrJobCNode != itrEnd;
00112 ++itrJobCNode) {
00113 os << i1(++i) << ") " << (**itrJobCNode) << "\n";
00114 }
00115
00116
00117 bool haveconnect = false;
00118 const JobCGraphVtx* v = 0;
00119 for (i=0; (v=this->GetAttached(i))!=0; ++i) {
00120 const JobCPath* p2 = dynamic_cast<const JobCPath*>(v);
00121 if (p2!=0 && haveconnect==false) {
00122 os << " |-->";
00123 }
00124 os << "/" << p2->GetName();
00125 haveconnect = true;
00126 }
00127 if (haveconnect) os << "/\n";
00128 }
00129
00130
00131
00132 ostream& operator<<(ostream& os, const JobCPath& p)
00133 {
00134 JobCPathConnectionHelper jcpph(&p);
00135 return jcpph.DoPrint(os);
00136 }
00137
00138
00139
00140 JobCPath::JobCPath() :
00141 fIsRefreshRun(false),
00142 fAtJobStart(true),
00143 fName(""),
00144 fNin(0),
00145 fNpass(0),
00146 fNfail(0),
00147 fMom(0),
00148 fInput(0),
00149 fDummyModule(0),
00150 fDummyNode(0)
00151 {
00152 MSG("JobC", Msg::kDebug) << " default constructor\n";
00153
00154 }
00155
00156
00157
00158 JobCPath::JobCPath(const char* name,
00159 MomNavigator* mom,
00160 JobCInputModule* inp) :
00161 fIsRefreshRun(false),
00162 fAtJobStart(true),
00163 fName(name),
00164 fNin(0),
00165 fNpass(0),
00166 fNfail(0),
00167 fMom(mom),
00168 fInput(inp),
00169 fDummyModule(0),
00170 fDummyNode(0)
00171 {
00172
00173
00174
00175
00176
00177
00178
00179 MSG("JobC", Msg::kDebug) << " input module at " << (void*)inp << endl;
00180
00181 }
00182
00183
00184
00185 JobCPath::~JobCPath()
00186 {
00187
00188
00189
00190 MSG("JobC", Msg::kVerbose) << this->GetName() << " destructor" << "\n";
00191
00192 #ifdef SITE_HAS_SIGC
00193 this->SigDelete(this);
00194 #endif
00195
00196
00197 list<JobCNode*>::iterator itrJobCNode;
00198 for (itrJobCNode = fNodeList.begin();
00199 itrJobCNode != fNodeList.end();
00200 ++itrJobCNode) {
00201 MSG("JobC", Msg::kVerbose) <<
00202 " >delete node " << (**itrJobCNode) << "\n";
00203 delete (*itrJobCNode);
00204 }
00205
00206
00207 list<JobCModule*>::iterator itrJobCModule;
00208 for (itrJobCModule = fModuleList.begin();
00209 itrJobCModule != fModuleList.end();
00210 ++itrJobCModule) {
00211 MSG("JobC", Msg::kVerbose) <<
00212 " >delete module " << (*itrJobCModule)->GetName() << "\n";
00213
00214
00215 (*itrJobCModule)->EndJob();
00216
00217 delete (*itrJobCModule);
00218 }
00219
00220 if (fDummyModule) { delete fDummyModule; fDummyModule = 0; }
00221 if (fDummyNode) { delete fDummyNode; fDummyNode = 0; }
00222 }
00223
00224
00225
00226 #ifdef SITE_HAS_SIGC
00227 void JobCPath::NodeUpdateCB(JobCNode* , JobCNode::Update_t u)
00228 {
00229
00230
00231
00232 switch (u) {
00233 case JobCNode::kFilter: this->SigUpdate(this,JobCPath::kFilters);
00234 default: this->SigUpdate(this,JobCPath::kGeneral);
00235 }
00236 }
00237 #endif
00238
00239
00240
00241 bool JobCPath::AtJobStart() const
00242 {
00243
00244
00245
00246 bool tmp = fAtJobStart;
00247 fAtJobStart = false;
00248 return tmp;
00249 }
00250
00251
00252
00253 void JobCPath::CheckResult(const JobCResult& r)
00254 {
00255
00256
00257
00258
00259
00260 MSG("JobC", Msg::kVerbose) << "CheckResult: Current result is " << r << endl;
00261
00262 if ( r.BeginFile() || r.EndFile() || r.BeginRun() || r.EndRun() ) {
00263 this->PropagateResult(r,this);
00264 }
00265 }
00266
00267
00268
00269 void JobCPath::HandleResult(const JobCResult& r) const
00270 {
00271
00272
00273
00274
00275 MSG("JobC", Msg::kVerbose) << "HandleResult: Current result is " << r << endl;
00276
00277 bool beginFile = r.BeginFile();
00278 bool endFile = r.EndFile();
00279 bool beginRun = r.BeginRun();
00280 bool endRun = r.EndRun();
00281
00282 list<JobCModule*>::const_iterator itrJobCModule;
00283 for (itrJobCModule = fModuleList.begin();
00284 itrJobCModule != fModuleList.end();
00285 ++itrJobCModule) {
00286 if (endFile) { (*itrJobCModule)->EndFile(); }
00287 if (endRun) { (*itrJobCModule)->EndRun(); }
00288 if (beginRun) { (*itrJobCModule)->BeginRun(); }
00289 if (beginFile) { (*itrJobCModule)->BeginFile(); }
00290 }
00291 }
00292
00293
00294
00295 void JobCPath::PropagateResult(const JobCResult& r, JobCPath* p)
00296 {
00297
00298
00299
00300
00301 JobCPathConnectionHelper h(p);
00302 h.DoHandleResult(r);
00303 }
00304
00305
00306
00307 const char* JobCPath::GetName() const { return fName.c_str(); }
00308
00309
00310
00311 JobCModule *JobCPath::GetModule(const char *moduleName, bool create)
00312 {
00313
00314
00315
00316
00317
00318
00319 list<JobCModule*>::iterator itrJobCModule(fModuleList.begin());
00320 list<JobCModule*>::iterator itrEnd(fModuleList.end());
00321 for (;itrJobCModule != itrEnd; ++itrJobCModule) {
00322 if (strcmp(moduleName,(*itrJobCModule)->GetName())==0) {
00323 MSG("JobC",Msg::kVerbose) <<
00324 "Found " << moduleName << " in path " << fName << "\n";
00325 return (*itrJobCModule);
00326 }
00327 }
00328
00329 if (create == false) return 0;
00330
00331
00332 JobCModuleProxy*
00333 jmp = JobCModuleRegistry::Instance().LookUp(moduleName);
00334 if (jmp) {
00335 JobCModule* m = jmp->CreateModule();
00336 m->SetPath(this);
00337 fModuleList.push_back(m);
00338 return m;
00339 }
00340
00341
00342 return 0;
00343 }
00344
00345
00346
00347 JobCNode* JobCPath::FindNode(const char* module, const char* method)
00348 {
00349
00350
00351
00352 list<JobCNode*>::const_iterator itr(fNodeList.begin());
00353 list<JobCNode*>::const_iterator itrEnd(fNodeList.end());
00354 for (; itr!=itrEnd; ++itr) {
00355 if ((*itr)->MatchModuleMethod(module,method)) {
00356 return (*itr);
00357 }
00358 }
00359 return 0;
00360 }
00361
00362 JobCInputModule* JobCPath::GetInputModule()
00363 {
00364 return fInput;
00365 }
00366
00367
00368
00369
00370 bool JobCPath::HandleError(const JobCResult& result, const JobCNode* n)
00371 {
00372
00373
00374
00375
00376
00377
00378
00379 JobCResult::Error_t errlvl = result.ErrorLevel();
00380 if (errlvl == JobCResult::kWarning) {
00381
00382 }
00383 else if (errlvl == JobCResult::kError) {
00384 MSG("JobC",Msg::kError) << "Error in: [" << (*n) << "]\n";
00385 }
00386 else {
00387 MSG("JobC",Msg::kFatal) <<
00388 "Fatal error in: [" << (*n) << "]\n";
00389 }
00390
00391
00392 JobCResult::Error_t errorThreshold = JobCResult::kError;
00393 if (errlvl < errorThreshold) return false;
00394
00395
00396 if (errlvl == JobCResult::kFatal) abort();
00397
00398 return true;
00399 }
00400
00401
00402
00403 JobCModule& JobCPath::Mod(const char* moduleName)
00404 {
00405
00406
00407
00408
00409
00410
00411 JobCModule* m = this->GetModule(moduleName, false);
00412 if (m) { return (*m); }
00413
00414 MSG("JobC",Msg::kWarning) <<
00415 "Path '" << this->GetName() << "' " <<
00416 "does not contain module '" << moduleName << "'.\n";
00417
00418
00419
00420 if (fDummyModule == 0) fDummyModule = new JobCModule;
00421 return (*fDummyModule);
00422 }
00423
00424
00425
00426 JobCNode& JobCPath::Node(const char* nodeName)
00427 {
00428
00429
00430
00431
00432
00433
00434 std::string module;
00435 std::string method;
00436 JobCommand::SplitLine(nodeName,':',module,method);
00437
00438 JobCNode* n = this->FindNode(module.c_str(),method.c_str());
00439 if (n) { return (*n); }
00440
00441 MSG("JobC",Msg::kWarning) <<
00442 "Path '" << this->GetName() << "' " <<
00443 "does contain node '" << nodeName << "'.\n";
00444
00445
00446
00447 if (fDummyNode == 0) fDummyNode = new JobCNode;
00448 return (*fDummyNode);
00449 }
00450
00451
00452
00453 JobCNode* JobCPath::CreateNode(const char* modName, const char* metName)
00454 {
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 JobCModule *module = this->GetModule(modName, true);
00465 if (module == 0) {
00466 MSG("JobC",Msg::kWarning) <<
00467 "Get failed for module '" << modName << "'.\n";
00468 return 0;
00469 }
00470
00471
00472 const JobCMethod* method = JobCMethod::GetMethodByName(metName);
00473 if (method == 0) {
00474 MSG("JobC",Msg::kWarning) <<
00475 "Look up failed for method '" << metName << "'\n";
00476 return 0;
00477 }
00478 MSG("JobC", Msg::kDebug) << "Created node "
00479 << module->GetName() << "::"
00480 << method->GetName() << "\n";
00481
00482
00483 JobCNode* n = new JobCNode(module, method);
00484 #ifdef SITE_HAS_SIGC
00485 if (n) {
00486
00487 n->SigUpdate.connect(SigC::slot_class(*this,&JobCPath::NodeUpdateCB));
00488 }
00489 #endif
00490 return n;
00491 }
00492
00493
00494
00495 void JobCPath::SetAllFilters(bool onOff)
00496 {
00497
00498
00499
00500 list<JobCNode*>::iterator itr(fNodeList.begin());
00501 list<JobCNode*>::iterator itrEnd(fNodeList.end());
00502 for (; itr!=itrEnd; ++itr) {
00503 if (onOff) {
00504 (*itr)->FilterOn();
00505 }
00506 else {
00507 (*itr)->FilterOff();
00508 }
00509 }
00510 }
00511
00512
00513
00514 void JobCPath::ReverseAllFilters()
00515 {
00516
00517
00518
00519 list<JobCNode*>::iterator itr(fNodeList.begin());
00520 list<JobCNode*>::iterator itrEnd(fNodeList.end());
00521 for (; itr!=itrEnd; ++itr) {
00522 (*itr)->ReverseFilter();
00523 }
00524 }
00525
00526
00527
00528 JobCNode* JobCPath::PushFront(const char *moduleName, const char *methodName)
00529 {
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 JobCNode *node = this->CreateNode(moduleName, methodName);
00540
00541
00542 if (node) {
00543 fNodeList.push_front(node);
00544 #ifdef SITE_HAS_SIGC
00545 this->SigUpdate(this,JobCPath::kAddNode);
00546 #endif
00547 }
00548 return node;
00549 }
00550
00551
00552
00553 JobCNode* JobCPath::PushBack(const char *moduleName, const char *methodName)
00554 {
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 JobCNode *node = this->CreateNode(moduleName, methodName);
00565 if (node == 0) {
00566 MSG("JobC", Msg::kWarning)
00567 << "Failed to create node "
00568 << moduleName << "::" << methodName << "\n";
00569 return 0;
00570 }
00571
00572
00573 if (node) {
00574 fNodeList.push_back(node);
00575 #ifdef SITE_HAS_SIGC
00576 this->SigUpdate(this,JobCPath::kAddNode);
00577 #endif
00578 }
00579 return node;
00580 }
00581
00582
00583
00584 JobCNode* JobCPath::AddAt(const char *moduleName,
00585 const char *methodName, int n)
00586 {
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 JobCNode *node = this->CreateNode(moduleName, methodName);
00597
00598
00599
00600
00601 list<JobCNode*>::iterator itrJobCNode = fNodeList.begin();
00602 for (int i=1; i<n; ++i) {
00603 if (++itrJobCNode == fNodeList.end()) break;
00604 }
00605
00606
00607 if (node) {
00608 fNodeList.insert(itrJobCNode, node);
00609 #ifdef SITE_HAS_SIGC
00610 this->SigUpdate(this,JobCPath::kAddNode);
00611 #endif
00612 }
00613
00614 return node;
00615 }
00616
00617
00618
00619 JobCNode* JobCPath::AddBetween(const char *moduleName,
00620 const char *methodName,
00621 const char *afterNodeName,
00622 const char *beforeNodeName)
00623 {
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 JobCNode* newNode = this->CreateNode(moduleName, methodName);
00636
00637 if(!newNode){
00638 MSG("JobCPath", Msg::kFatal) << "Could not create node "
00639 << moduleName << ":" << methodName << endl;
00640 return 0;
00641 }
00642
00643
00644 std::string afterModule, afterMethod;
00645 JobCommand::SplitLine(afterNodeName, ':', afterModule, afterMethod);
00646 JobCNode* afterNode = this->FindNode(afterModule.c_str() ,afterMethod.c_str());
00647
00648
00649 std::string beforeModule, beforeMethod;
00650 JobCommand::SplitLine(beforeNodeName, ':', beforeModule, beforeMethod);
00651 JobCNode* beforeNode = this->FindNode(beforeModule.c_str() ,beforeMethod.c_str());
00652
00653 if(!afterNode){
00654 MSG("JobCPath", Msg::kFatal) << "Could not find node "
00655 << afterNodeName << endl;
00656 return 0;
00657 }
00658 if(!beforeNode){
00659 MSG("JobCPath", Msg::kFatal) << "Could not find node "
00660 << beforeNodeName << endl;
00661 return 0;
00662 }
00663
00664 list<JobCNode*>::iterator it = fNodeList.begin();
00665
00666 for(; it != fNodeList.end(); ++it){
00667 if(*it == afterNode){
00668
00669 ++it;
00670
00671 if(it != fNodeList.end() && *it == beforeNode){
00672 fNodeList.insert(it, newNode);
00673 #ifdef SITE_HAS_SIGC
00674 this->SigUpdate(this, JobCPath::kAddNode);
00675 #endif
00676 return newNode;
00677 }
00678 else{
00679 MSG("JobCPath", Msg::kFatal) << afterNodeName
00680 << " and "
00681 << beforeNodeName
00682 << " are not adjacent\n";
00683 return 0;
00684 }
00685 }
00686 }
00687
00688 MSG("JobCPath", Msg::kFatal) << "This should never happen.\n";
00689 return 0;
00690 }
00691
00692
00693
00694 void JobCPath::Remove(const char *moduleName, const char *methodName)
00695 {
00696
00697
00698
00699
00700
00701
00702
00703 bool haveMatch = false;
00704 list<JobCNode*>::iterator itrJobCNode(fNodeList.begin());
00705 list<JobCNode*>::iterator itrEnd(fNodeList.end());
00706 for (;itrJobCNode != itrEnd; ++itrJobCNode) {
00707 if ( (haveMatch =
00708 (*itrJobCNode)->MatchModuleMethod(moduleName, methodName))) {
00709 break;
00710 }
00711 }
00712
00713 if (haveMatch) {
00714
00715 delete (*itrJobCNode);
00716
00717
00718 fNodeList.erase(itrJobCNode);
00719 #ifdef SITE_HAS_SIGC
00720 this->SigUpdate(this,JobCPath::kRemoveNode);
00721 #endif
00722 return;
00723 }
00724
00725
00726 MSG("JobC", Msg::kWarning)
00727 << "Path does not contain "
00728 << moduleName << "::" << methodName << ".\n";
00729 }
00730
00731
00732
00733 bool JobCPath::EvalInput(JobCRecord* rec)
00734 {
00735
00736
00737
00738
00739 JobCResult result = this->Execute(rec);
00740 MSG("JobC", Msg::kVerbose) << "EvalInput gets result = " << result << endl;
00741
00742
00743
00744
00745 if ( result.EndOfInputStream() || result.Failed() ) return false;
00746 return true;
00747 }
00748
00749
00750
00751 void JobCPath::Attach(JobCGraphVtx *p)
00752 {
00753
00754
00755
00756 this->JobCGraphVtx::Attach(p);
00757 #ifdef SITE_HAS_SIGC
00758 this->SigUpdate(this,JobCPath::kAddConnection);
00759 #endif
00760 }
00761
00762
00763
00764 void JobCPath::Detach(JobCGraphVtx *p)
00765 {
00766
00767
00768
00769 this->JobCGraphVtx::Detach(p);
00770 #ifdef SITE_HAS_SIGC
00771 this->SigUpdate(this,JobCPath::kRemoveConnection);
00772 #endif
00773 }
00774
00775
00776
00777 JobCResult JobCPath::Execute(JobCRecord* rec)
00778 {
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 ++fNin;
00789
00790
00791 list<JobCNode*>::iterator itrJobCNode(fNodeList.begin());
00792 list<JobCNode*>::iterator itrEnd(fNodeList.end());
00793 for (;itrJobCNode != itrEnd; ++itrJobCNode) {
00794
00795
00796
00797 JobCMethod m = (*itrJobCNode)->GetMethod();
00798
00799
00800
00801 if (fInput==0 && (fIsRefreshRun == true) && (m == JobCMethod::kGet)) {
00802 continue;
00803 }
00804
00805
00806 MsgTripWire::Instance().StartNode();
00807 fResult = (*itrJobCNode)->Execute(rec->GetDataPtr());
00808 MSG("JobC", Msg::kVerbose) << "Result of node " << *(*itrJobCNode) << "execution is: " << fResult << endl;
00809
00810
00811
00812
00813 if (fResult.HaveError()) {
00814 bool stopRun = this->HandleError(fResult,(*itrJobCNode));
00815 if (stopRun) return fResult;
00816 }
00817
00818
00819
00820 if ( fResult.EndOfInputStream() ) {
00821 --fNin;
00822 return fResult;
00823 }
00824
00825
00826 if ( fResult.NonPhysicsRecord() ) rec->SetIsPhysics(false);
00827
00828
00829 this->CheckResult(fResult);
00830
00831
00832 if (fResult.Failed()) {
00833 ++fNfail;
00834 return fResult;
00835 }
00836 }
00837
00838
00839 ++fNpass;
00840 return fResult;
00841 }
00842
00843
00844
00845 void JobCPath::BeginJob() const
00846 {
00847
00848
00849
00850
00851
00852
00853
00854 list<JobCModule*>::const_iterator i(fModuleList.begin());
00855 list<JobCModule*>::const_iterator iEnd(fModuleList.end());
00856 for (; i!=iEnd; ++i) if (*i) (*i)->BeginJob();
00857
00858 }
00859
00860
00861
00862 void JobCPath::SetRefreshMode(bool m) const
00863 {
00864
00865 fIsRefreshRun = m;
00866 }
00867
00868
00869
00870 void JobCPath::PropagateRefreshMode(bool m)
00871 {
00872
00873
00874
00875 JobCPathConnectionHelper h(this);
00876 h.SetRefreshMode(m);
00877 }
00878
00879
00880
00881 void JobCPath::Report() { MSG("JobCReport",Msg::kInfo) << (*this) << "\n"; }
00882
00883
00884
00885 void JobCPath::Run(int n, JobCPath::RunMode_t runmode)
00886 {
00887
00888
00889
00890
00891 assert(fMom);
00892 JobCRecord rec(fMom);
00893
00894 this->SetUniquePaths();
00895
00896 #ifdef SITE_HAS_SIGC
00897 this->SigStartRun(this);
00898 #endif
00899
00900
00901 if (n == 0) {
00902 this->PropagateRefreshMode(true);
00903 this->EvaluateGraph(&rec);
00904 this->PropagateRefreshMode(false);
00905 #ifdef SITE_HAS_SIGC
00906 this->SigEndRun(this);
00907 #endif
00908 return;
00909 }
00910 else {
00911
00912
00913
00914
00915 if (this->AtJobStart()) {
00916 JobCPathConnectionHelper h(this);
00917 h.DoBeginJob();
00918 }
00919
00920
00921 bool done = false;
00922 int nIn0 = fNin;
00923 int nPass0 = fNpass;
00924 int nFail0 = fNfail;
00925 while (done == false) {
00926 MsgTripWire::Instance().StartRecordSet();
00927 rec.Reset();
00928 if (fInput) {
00929 fResult = fInput->Next();
00930
00931 (MsgService::Instance())->SetCurrentRunSnarl(fInput->GetCurrentRun(),
00932 fInput->GetCurrentSnarl());
00933
00934 MSG("JobC", Msg::kVerbose) << "Result input module is: "
00935 << fResult << endl;
00936 this->CheckResult(fResult);
00937
00938 if (fResult.EndOfInputStream()) {
00939 done |= true;
00940 break;
00941 }
00942 }
00943 this->EvaluateGraph(&rec);
00944
00945
00946
00947 done |= ( (runmode == JobCPath::kRunAll) && (false) );
00948 done |= ( (runmode == JobCPath::kRunNin) && (fNin -nIn0 )==n );
00949 done |= ( (runmode == JobCPath::kRunNpass) && (fNpass-nPass0)==n );
00950 done |= ( (runmode == JobCPath::kRunNfail) && (fNfail-nFail0)==n );
00951
00952
00953 if (fResult.EndOfInputStream()) done |= true;
00954
00955
00956 if (JobCEnv::Instance().ContinueRun(fNin) == false) {
00957 done |= true;
00958 }
00959
00960
00961 if ( (fNin-nIn0)==JOBCPATH_RUN_LIMIT ) {
00962 MSG("JobC",Msg::kWarning) <<
00963 "Run limit (" << JOBCPATH_RUN_LIMIT << " records) reached.\n";
00964 done |= true;
00965 }
00966 }
00967 }
00968 #ifdef SITE_HAS_SIGC
00969 this->SigEndRun(this);
00970 #endif
00971 }
00972
00973
00974
00975 void JobCPath::RunNin(int n)
00976 {
00977
00978
00979
00980
00981 this->Run(n,JobCPath::kRunNin);
00982 }
00983
00984
00985
00986 void JobCPath::RunNpass(int n)
00987 {
00988
00989
00990
00991 this->Run(n,JobCPath::kRunNpass);
00992 }
00993
00994
00995
00996 void JobCPath::RunNfail(int n)
00997 {
00998
00999
01000
01001 this->Run(n,JobCPath::kRunNfail);
01002 }
01003 void JobCPath::SetUniquePaths(const char* base)
01004 {
01005 string path = Form("%s/%s",base,fName.c_str());
01006
01007 list<JobCNode*>::const_iterator nit, done = fNodeList.end();
01008 for (nit = fNodeList.begin(); nit != done; ++nit) {
01009 JobCModule* mod = (*nit)->GetModule();
01010 string name = Form("%s/%s",path.c_str(),mod->GetName());
01011 mod->SetUniqueName(name.c_str());
01012 }
01013
01014 JobCGraphVtx* v = 0;
01015 for (int ind = 0; (v=this->GetAttached(ind))!=0; ++ind) {
01016 JobCPath* p2 = dynamic_cast<JobCPath*>(v);
01017 p2->SetUniquePaths(path.c_str());
01018 }
01019 }
01020