artdaq  v3_04_01
BoardReaderApp.cc
1 #define TRACE_NAME (app_name + "_BoardReaderApp").c_str()
2 #include "artdaq/DAQdata/Globals.hh"
3 #include "artdaq/Application/BoardReaderApp.hh"
4 
6  : fragment_receiver_ptr_(nullptr)
7 {
8 }
9 
10 // *******************************************************************
11 // *** The following methods implement the state machine operations.
12 // *******************************************************************
13 
14 bool artdaq::BoardReaderApp::do_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
15 {
16  report_string_ = "";
17  external_request_status_ = true;
18 
19  // in the following block, we first destroy the existing BoardReader
20  // instance, then create a new one. Doing it in one step does not
21  // produce the desired result since that creates a new instance and
22  // then deletes the old one, and we need the opposite order.
23  TLOG(TLVL_DEBUG) << "Initializing first deleting old instance " << (void*)fragment_receiver_ptr_.get();
24  fragment_receiver_ptr_.reset(nullptr);
25  fragment_receiver_ptr_.reset(new BoardReaderCore(*this));
26  TLOG(TLVL_DEBUG) << "Initializing new BoardReaderCore at " << (void*)fragment_receiver_ptr_.get() << " with pset " << pset.to_string();
27  external_request_status_ = fragment_receiver_ptr_->initialize(pset, timeout, timestamp);
28  if (!external_request_status_)
29  {
30  report_string_ = "Error initializing ";
31  report_string_.append(app_name + " ");
32  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
33  }
34 
35  TLOG(TLVL_DEBUG) << "do_initialize(fhicl::ParameterSet, uint64_t, uint64_t): "
36  << "Done initializing.";
37  return external_request_status_;
38 }
39 
40 bool artdaq::BoardReaderApp::do_start(art::RunID id, uint64_t timeout, uint64_t timestamp)
41 {
42  report_string_ = "";
43  external_request_status_ = fragment_receiver_ptr_->start(id, timeout, timestamp);
44  if (!external_request_status_)
45  {
46  report_string_ = "Error starting ";
47  report_string_.append(app_name + " ");
48  report_string_.append("for run number ");
49  report_string_.append(boost::lexical_cast<std::string>(id.run()));
50  report_string_.append(", timeout ");
51  report_string_.append(boost::lexical_cast<std::string>(timeout));
52  report_string_.append(", timestamp ");
53  report_string_.append(boost::lexical_cast<std::string>(timestamp));
54  report_string_.append(".");
55  }
56 
57  boost::thread::attributes attrs;
58  attrs.set_stack_size(4096 * 2000); // 8 MB
59  try {
60  fragment_processing_thread_ = boost::thread(attrs, boost::bind(&BoardReaderCore::process_fragments, fragment_receiver_ptr_.get()));
61  }
62  catch (const boost::exception& e)
63  {
64  TLOG(TLVL_ERROR) << "Caught boost::exception starting Fragment Processing thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
65  std::cerr << "Caught boost::exception starting Fragment Processing thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
66  exit(5);
67  }
68  /*
69  fragment_processing_future_ =
70  std::async(std::launch::async, &BoardReaderCore::process_fragments,
71  fragment_receiver_ptr_.get());*/
72 
73  return external_request_status_;
74 }
75 
76 bool artdaq::BoardReaderApp::do_stop(uint64_t timeout, uint64_t timestamp)
77 {
78  report_string_ = "";
79  external_request_status_ = fragment_receiver_ptr_->stop(timeout, timestamp);
80  if (!external_request_status_)
81  {
82  report_string_ = "Error stopping ";
83  report_string_.append(app_name + ".");
84  return false;
85  }
86  if (fragment_processing_thread_.joinable())
87  {
88  TLOG(TLVL_DEBUG) << "Joining fragment processing thread";
89  fragment_processing_thread_.join();
90  }
91 
92  TLOG(TLVL_DEBUG) << "BoardReader Stopped. Getting run statistics";
93  int number_of_fragments_sent = -1;
94  if(fragment_receiver_ptr_) number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
95  TLOG(TLVL_DEBUG) << "do_stop(uint64_t, uint64_t): "
96  << "Number of fragments sent = " << number_of_fragments_sent
97  << ".";
98 
99  return external_request_status_;
100 }
101 
102 bool artdaq::BoardReaderApp::do_pause(uint64_t timeout, uint64_t timestamp)
103 {
104  report_string_ = "";
105  external_request_status_ = fragment_receiver_ptr_->pause(timeout, timestamp);
106  if (!external_request_status_)
107  {
108  report_string_ = "Error pausing ";
109  report_string_.append(app_name + ".");
110  }
111 
112  if(fragment_processing_thread_.joinable()) fragment_processing_thread_.join();
113  int number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
114  TLOG(TLVL_DEBUG) << "do_pause(uint64_t, uint64_t): "
115  << "Number of fragments sent = " << number_of_fragments_sent
116  << ".";
117 
118  return external_request_status_;
119 }
120 
121 bool artdaq::BoardReaderApp::do_resume(uint64_t timeout, uint64_t timestamp)
122 {
123  report_string_ = "";
124  external_request_status_ = fragment_receiver_ptr_->resume(timeout, timestamp);
125  if (!external_request_status_)
126  {
127  report_string_ = "Error resuming ";
128  report_string_.append(app_name + ".");
129  }
130 
131  boost::thread::attributes attrs;
132  attrs.set_stack_size(4096 * 2000); // 8 MB
133  fragment_processing_thread_ = boost::thread(attrs, boost::bind(&BoardReaderCore::process_fragments, fragment_receiver_ptr_.get()));
134  /*
135  fragment_processing_future_ =
136  std::async(std::launch::async, &BoardReaderCore::process_fragments,
137  fragment_receiver_ptr_.get());*/
138 
139  return external_request_status_;
140 }
141 
143 {
144  report_string_ = "";
145  external_request_status_ = fragment_receiver_ptr_->shutdown(timeout);
146  // 02-Jun-2018, ELF & KAB: it's very, very unlikely that the following call is needed,
147  // but just in case...
148  if (fragment_processing_thread_.joinable()) fragment_processing_thread_.join();
149  if (!external_request_status_)
150  {
151  report_string_ = "Error shutting down ";
152  report_string_.append(app_name + ".");
153  }
154  return external_request_status_;
155 }
156 
157 bool artdaq::BoardReaderApp::do_soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
158 {
159  report_string_ = "";
160  external_request_status_ = fragment_receiver_ptr_->soft_initialize(pset, timeout, timestamp);
161  if (!external_request_status_)
162  {
163  report_string_ = "Error soft-initializing ";
164  report_string_.append(app_name + " ");
165  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
166  }
167  return external_request_status_;
168 }
169 
170 bool artdaq::BoardReaderApp::do_reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
171 {
172  external_request_status_ = fragment_receiver_ptr_->reinitialize(pset, timeout, timestamp);
173  if (!external_request_status_)
174  {
175  report_string_ = "Error reinitializing ";
176  report_string_.append(app_name + " ");
177  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
178  }
179  return external_request_status_;
180 }
181 
183 {
184  TLOG(TLVL_DEBUG) << "Booted state entry action called.";
185 
186  // the destruction of any existing BoardReaderCore has to happen in the
187  // Booted Entry action rather than the Initialized Exit action because the
188  // Initialized Exit action is only called after the "init" transition guard
189  // condition is executed.
190  fragment_receiver_ptr_.reset(nullptr);
191 }
192 
193 bool artdaq::BoardReaderApp::do_meta_command(std::string const& command, std::string const& arg)
194 {
195  external_request_status_ = fragment_receiver_ptr_->metaCommand(command, arg);
196  if (!external_request_status_)
197  {
198  report_string_ = "Error running meta-command on ";
199  report_string_.append(app_name + " ");
200  report_string_.append("with command = \"" + command + "\", arg = \"" + arg + "\".");
201  }
202  return external_request_status_;
203 }
204 
205 std::string artdaq::BoardReaderApp::report(std::string const& which) const
206 {
207  std::string resultString;
208 
209  // if all that is requested is the latest state change result, return it
210  if (which == "transition_status")
211  {
212  if (report_string_.length() > 0) { return report_string_; }
213  else { return "Success"; }
214  }
215 
218  //if (report_string_.length() > 0) {
219  // resultString.append("*** Overall status message:\r\n");
220  // resultString.append(report_string_ + "\r\n");
221  // resultString.append("*** Requested report response:\r\n");
222  //}
223 
224  // pass the request to the BoardReaderCore instance, if it's available
225  if (fragment_receiver_ptr_.get() != 0)
226  {
227  resultString.append(fragment_receiver_ptr_->report(which));
228  }
229  else
230  {
231  resultString.append("This BoardReader has not yet been initialized and ");
232  resultString.append("therefore can not provide reporting.");
233  }
234 
235  return resultString;
236 }
bool do_soft_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Soft-Initialize the BoardReaderCore.
bool do_resume(uint64_t timeout, uint64_t timestamp) override
Resume the BoardReaderCore.
bool do_stop(uint64_t timeout, uint64_t timestamp) override
Stop the BoardReaderCore.
BoardReaderCore implements the state machine for the BoardReader artdaq application. It contains a CommandableFragmentGenerator, which generates Fragments which are then sent to a DataSenderManager by BoardReaderCore.
bool do_meta_command(std::string const &command, std::string const &arg) override
Perform a user-defined command (passed to CommandableFragmentGenerator)
bool do_shutdown(uint64_t timeout) override
Shutdown the BoardReaderCore.
bool do_reinitialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Reinitialize the BoardReaderCore.
std::string report(std::string const &which) const override
If which is &quot;transition_status&quot;, report the status of the last transition. Otherwise pass through to ...
BoardReaderApp()
BoardReaderApp Constructor.
void BootedEnter() override
Action taken upon entering the &quot;Booted&quot; state.
void process_fragments()
Main working loop of the BoardReaderCore.
bool do_start(art::RunID id, uint64_t timeout, uint64_t timestamp) override
Start the BoardReaderCore.
bool do_initialize(fhicl::ParameterSet const &pset, uint64_t timeout, uint64_t timestamp) override
Initialize the BoardReaderCore.
bool do_pause(uint64_t timeout, uint64_t timestamp) override
Pause the BoardReaderCore.