otsdaq  v2_05_02_indev
FEDataManagerSupervisor.cc
1 #include "otsdaq/CoreSupervisors/FEDataManagerSupervisor.h"
2 
3 #include "../ARTDAQDataManager/ARTDAQDataManager.h"
4 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
5 #include "otsdaq/DataManager/DataManager.h"
6 #include "otsdaq/DataManager/DataManagerSingleton.h"
7 
8 //#include "otsdaq/FECore/FEProducerVInterface.h"
9 
10 using namespace ots;
11 
12 XDAQ_INSTANTIATOR_IMPL(FEDataManagerSupervisor)
13 
14 //==============================================================================
15 FEDataManagerSupervisor::FEDataManagerSupervisor(xdaq::ApplicationStub* s, bool artdaqDataManager) : FESupervisor(s)
16 {
17  __SUP_COUT__ << "Constructor." << __E__;
18 
19  // WARNING THE ORDER IS IMPORTANT SINCE THE FIRST STATE MACHINE ELEMENT
20  // WILL BE CALLED FIRST DURING TRANSITION!!!!!
21 
22  // the FE Interfaces Manager is added first, and then the Data Manager
23  // So on FSM transitions, front-ends will transition first.
24 
25  // FEVInterfacesManager gets added in FESupervisor constructor
26  __SUP_COUTV__(CoreSupervisorBase::theStateMachineImplementation_.size());
27 
28  //
29  // CoreSupervisorBase::theStateMachineImplementation_.push_back(
30  // new FEVInterfacesManager(
31  // CorePropertySupervisorBase::getContextTreeNode(),
32  // CorePropertySupervisorBase::supervisorConfigurationPath_
33  // )
34  // );
35 
36  if(artdaqDataManager)
37  {
38  __SUP_COUT__ << "Adding ARTDAQ Data Manager now...!" << __E__;
39  CoreSupervisorBase::theStateMachineImplementation_.push_back(
40  DataManagerSingleton::getInstance<ARTDAQDataManager>(CorePropertySupervisorBase::getContextTreeNode(),
41  CorePropertySupervisorBase::getSupervisorConfigurationPath(),
42  CorePropertySupervisorBase::getSupervisorUID()));
43  }
44  else
45  {
46  __SUP_COUT__ << "Adding Data Manager now...!" << __E__;
47  CoreSupervisorBase::theStateMachineImplementation_.push_back(
48  DataManagerSingleton::getInstance<DataManager>(CorePropertySupervisorBase::getContextTreeNode(),
49  CorePropertySupervisorBase::getSupervisorConfigurationPath(),
50  CorePropertySupervisorBase::getSupervisorUID()));
51  }
52 
53  extractDataManager();
54 
55  __SUP_COUT__ << "Constructed." << __E__;
56 } // end constructor()
57 
58 //==============================================================================
59 FEDataManagerSupervisor::~FEDataManagerSupervisor(void)
60 {
61  __SUP_COUT__ << "Destroying..." << __E__;
62 
63  // theStateMachineImplementation_ is reset and the object it points to deleted in
64  // ~CoreSupervisorBase() This destructor must happen before the CoreSupervisor
65  // destructor
66 
67  DataManagerSingleton::deleteInstance(CoreSupervisorBase::getSupervisorUID());
68  theStateMachineImplementation_.pop_back();
69 
70  __SUP_COUT__ << "Destructed." << __E__;
71 } // end destructor()
72 
73 //==============================================================================
74 // transitionConfiguring
75 // swap order of state machine vector for configuring
76 // so that DataManager gets configured first.
77 void FEDataManagerSupervisor::transitionConfiguring(toolbox::Event::Reference e)
78 {
79  __SUP_COUT__ << "transitionConfiguring" << __E__;
80 
81  theDataManager_->parentSupervisorHasFrontends_ = true;
82 
83  // Data Manager needs to be configured (instantiate buffers)
84  // before FEVinterfaceManager configures (creates interfaces)
85 
86  if(theStateMachineImplementation_.size() != 2)
87  {
88  __SUP_SS__ << "State machine size is not 2! It is " << theStateMachineImplementation_.size() << ". What happened??" << __E__;
89  __SUP_SS_THROW__;
90  }
91 
92  VStateMachine* p = theStateMachineImplementation_[0];
93  theStateMachineImplementation_[0] = theStateMachineImplementation_[1];
94  theStateMachineImplementation_[1] = p;
95 
96  CoreSupervisorBase::transitionConfiguring(e);
97 
98  { // print buffer status
99  __SUP_SS__;
100  // theDataManager_->dumpStatus((std::ostream*)&ss);
101  std::cout << ss.str() << __E__;
102  }
103 
104  // At this point the buffers have been made with producers and consumers
105  // then the FEs (including FEProducers) were made.
106  // Producers (including FEProducers) and Consumers attach to their DataManager
107  // Buffer during their construction.
108 
109  // revert state machine order back
110  theStateMachineImplementation_[1] = theStateMachineImplementation_[0];
111  theStateMachineImplementation_[0] = p;
112 
113 } // end transitionConfiguring()
114 
115 //==============================================================================
116 // transitionStarting
117 // swap order of state machine vector for starting
118 // so that DataManager gets configured first.
119 // buffers need to be ready before FEs start writing to them
120 void FEDataManagerSupervisor::transitionStarting(toolbox::Event::Reference e)
121 {
122  __SUP_COUT__ << "transitionStarting" << __E__;
123 
124  // Data Manager needs to be started (start buffers)
125  // before FEVinterfaceManager starts (interfaces write)
126 
127  if(theStateMachineImplementation_.size() != 2)
128  {
129  __SUP_SS__ << "State machine size is not 2! It is " << theStateMachineImplementation_.size() << ". What happened??" << __E__;
130  }
131 
132  VStateMachine* p = theStateMachineImplementation_[0];
133  theStateMachineImplementation_[0] = theStateMachineImplementation_[1];
134  theStateMachineImplementation_[1] = p;
135 
136  CoreSupervisorBase::transitionStarting(e);
137 
138  // revert state machine order back
139  theStateMachineImplementation_[1] = theStateMachineImplementation_[0];
140  theStateMachineImplementation_[0] = p;
141 
142 } // end transitionStarting()
143 
144 //==============================================================================
145 // transitionResuming
146 // swap order of state machine vector for resuming
147 // so that DataManager gets configured first.
148 // buffers need to be ready before FEs start writing to them
149 void FEDataManagerSupervisor::transitionResuming(toolbox::Event::Reference e)
150 {
151  __SUP_COUT__ << "transitionStarting" << __E__;
152 
153  // Data Manager needs to be resumed (resume buffers)
154  // before FEVinterfaceManager resumes (interfaces write)
155 
156  if(theStateMachineImplementation_.size() != 2)
157  {
158  __SUP_SS__ << "State machine size is not 2! It is " << theStateMachineImplementation_.size() << ". What happened??" << __E__;
159  }
160 
161  VStateMachine* p = theStateMachineImplementation_[0];
162  theStateMachineImplementation_[0] = theStateMachineImplementation_[1];
163  theStateMachineImplementation_[1] = p;
164 
165  CoreSupervisorBase::transitionResuming(e);
166 
167  // revert state machine order back
168  theStateMachineImplementation_[1] = theStateMachineImplementation_[0];
169  theStateMachineImplementation_[0] = p;
170 
171 } // end transitionResuming()
172 
173 //==============================================================================
174 // extractDataManager
175 //
176 // locates theDataManager in state machines vector and
177 // returns 0 if not found.
178 //
179 // Note: this code assumes a CoreSupervisorBase has only one
180 // DataManager in its vector of state machines
181 DataManager* FEDataManagerSupervisor::extractDataManager()
182 {
183  theDataManager_ = 0;
184 
185  for(unsigned int i = 0; i < theStateMachineImplementation_.size(); ++i)
186  {
187  try
188  {
189  theDataManager_ = dynamic_cast<DataManager*>(theStateMachineImplementation_[i]);
190  if(!theDataManager_)
191  {
192  // dynamic_cast returns null pointer on failure
193  throw(std::runtime_error(""));
194  }
195  __SUP_COUT__ << "State Machine " << i << " WAS of type DataManager" << __E__;
196 
197  break;
198  }
199  catch(...)
200  {
201  __SUP_COUT__ << "State Machine " << i << " was NOT of type DataManager" << __E__;
202  }
203  }
204 
205  __SUP_COUT__ << "theDataManager pointer = " << theDataManager_ << __E__;
206 
207  return theDataManager_;
208 } // end extractDataManager()