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