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