otsdaq  v2_01_00
WorkLoop.cc
1 #include "otsdaq-core/WorkLoopManager/WorkLoop.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 
5 #include <toolbox/task/WorkLoopFactory.h>
6 
7 #include <iostream>
8 #include <unistd.h>
9 
10 using namespace ots;
11 
12 
13 //========================================================================================================================
14 WorkLoop::WorkLoop(std::string name)
15 : continueWorkLoop_(false)
16 , cWorkLoopName_ (name)
17 , cWorkLoopType_ ("waiting")
18 , workLoop_ (0)
19 , job_ (toolbox::task::bind(this, &WorkLoop::workLoopThread, cWorkLoopName_))
20 {
21 }
22 
23 //========================================================================================================================
24 WorkLoop::~WorkLoop(void)
25 {
26  mf::LogDebug("WorkLoop") << "Destroying WorkLoop: " << cWorkLoopName_ << std::endl;
27  if(stopWorkLoop())
28  toolbox::task::getWorkLoopFactory()->removeWorkLoop(cWorkLoopName_, cWorkLoopType_);
29  mf::LogDebug("WorkLoop") << "Destroyed WorkLoop: " << cWorkLoopName_ << std::endl;
30 }
31 
32 //========================================================================================================================
33 void WorkLoop::startWorkLoop(void)
34 {
35  //__COUT__ << "Starting WorkLoop: " << cWorkLoopName_ << std::endl;
36  continueWorkLoop_ = true;
37  try
38  {
39  workLoop_ = toolbox::task::getWorkLoopFactory()->getWorkLoop(cWorkLoopName_, cWorkLoopType_);
40  }
41  catch (xcept::Exception & e)
42  {
43  __COUT__ << "ERROR: Can't create WorkLoop job for " << cWorkLoopName_ << std::endl;
44  stopWorkLoop();
45  }
46 
47  if(workLoop_->isActive()) return;//This might be a consumer producer running at the same time so it has been activated already
48 
49  try
50  {
51  workLoop_->submit(job_);
52  }
53  catch (xcept::Exception & e)
54  {
55  __COUT__ << "ERROR: Can't submit WorkLoop job for " << cWorkLoopName_ << std::endl;
56  stopWorkLoop();
57  }
58 
59  try
60  {
61  workLoop_->activate();
62  }
63  catch (xcept::Exception & e)
64  {
65  __COUT__ << "ERROR: Can't activate WorkLoop job for " << cWorkLoopName_
66  << " Very likely because the name " << cWorkLoopName_ << " is not unique!" << std::endl;
67  stopWorkLoop();
68  }
69 }
70 
71 //========================================================================================================================
72 bool WorkLoop::stopWorkLoop()
73 {
74  __COUT__ << "Stopping WorkLoop: " << cWorkLoopName_ << std::endl;
75 
76  continueWorkLoop_ = false;
77  if(workLoop_ == 0)
78  {
79  __COUT__ << "MEASSAGE: WorkLoop " << cWorkLoopName_ << " was not created at all! This message will be commented in the future" << std::endl;
80  return false;
81  }
82 
83  __COUT__ << "initially workLoop_->isActive() " << (workLoop_->isActive()?"yes":"no") << std::endl;
84 
85  try
86  {
87  //THis method waits until the workloop job returns! Super cool!
88  workLoop_->cancel();
89  }
90  catch (xcept::Exception & e)
91  {
92  __COUT__ << "WARNING: Can't cancel WorkLoop job for " << cWorkLoopName_ <<
93  " because probably it has never been activated!" << std::endl;
94 
95  __COUT__ << "workLoop_->isActive() " << (workLoop_->isActive()?"yes":"no") << std::endl;
96  return true;
97  }
98 
99  try
100  {
101  workLoop_->remove(job_);
102  }
103  catch (xcept::Exception & e)
104  {
105  // ATTENTION!
106  // If the workloop job thread returns false, then the workloop job is automatically removed and it can't be removed again
107  // Leaving this try catch allows me to be general in the job threads so I can return true (repeat loop) or false ( loop only once)
108  // without crashing
109  __COUT__ << "WARNING: Can't remove request WorkLoop: " << cWorkLoopName_ << std::endl;
110  __COUT__ << "workLoop_->isActive() " << (workLoop_->isActive()?"yes":"no") << std::endl;
111  }
112 
113  __COUT__ << "Stopped WorkLoop: " << cWorkLoopName_ << std::endl;
114  __COUT__ << "workLoop_->isActive() " << (workLoop_->isActive()?"yes":"no") << std::endl;
115  return true;
116 }
117 
118 //========================================================================================================================
119 const std::string& WorkLoop::getWorkLoopName(void)
120 {
121  return cWorkLoopName_;
122 }
123 
124 //========================================================================================================================
125 bool WorkLoop::isActive(void)
126 {
127  return workLoop_->isActive() && continueWorkLoop_;
128 }