artdaq  v3_07_01
BoardReaderApp.cc
1 #include "artdaq/DAQdata/Globals.hh"
2 #define TRACE_NAME (app_name + "_BoardReaderApp").c_str()
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  {
61  fragment_processing_thread_ = boost::thread(attrs, boost::bind(&BoardReaderCore::process_fragments, fragment_receiver_ptr_.get()));
62  }
63  catch (const boost::exception& e)
64  {
65  TLOG(TLVL_ERROR) << "Caught boost::exception starting Fragment Processing thread: " << boost::diagnostic_information(e) << ", errno=" << errno;
66  std::cerr << "Caught boost::exception starting Fragment Processing thread: " << boost::diagnostic_information(e) << ", errno=" << errno << std::endl;
67  exit(5);
68  }
69  /*
70  fragment_processing_future_ =
71  std::async(std::launch::async, &BoardReaderCore::process_fragments,
72  fragment_receiver_ptr_.get());*/
73 
74  return external_request_status_;
75 }
76 
77 bool artdaq::BoardReaderApp::do_stop(uint64_t timeout, uint64_t timestamp)
78 {
79  report_string_ = "";
80  external_request_status_ = fragment_receiver_ptr_->stop(timeout, timestamp);
81  if (!external_request_status_)
82  {
83  report_string_ = "Error stopping ";
84  report_string_.append(app_name + ".");
85  return false;
86  }
87  if (fragment_processing_thread_.joinable())
88  {
89  TLOG(TLVL_DEBUG) << "Joining fragment processing thread";
90  fragment_processing_thread_.join();
91  }
92 
93  TLOG(TLVL_DEBUG) << "BoardReader Stopped. Getting run statistics";
94  int number_of_fragments_sent = -1;
95  if (fragment_receiver_ptr_) number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
96  TLOG(TLVL_DEBUG) << "do_stop(uint64_t, uint64_t): "
97  << "Number of fragments sent = " << number_of_fragments_sent
98  << ".";
99 
100  return external_request_status_;
101 }
102 
103 bool artdaq::BoardReaderApp::do_pause(uint64_t timeout, uint64_t timestamp)
104 {
105  report_string_ = "";
106  external_request_status_ = fragment_receiver_ptr_->pause(timeout, timestamp);
107  if (!external_request_status_)
108  {
109  report_string_ = "Error pausing ";
110  report_string_.append(app_name + ".");
111  }
112 
113  if (fragment_processing_thread_.joinable()) fragment_processing_thread_.join();
114  int number_of_fragments_sent = fragment_receiver_ptr_->GetFragmentsProcessed();
115  TLOG(TLVL_DEBUG) << "do_pause(uint64_t, uint64_t): "
116  << "Number of fragments sent = " << number_of_fragments_sent
117  << ".";
118 
119  return external_request_status_;
120 }
121 
122 bool artdaq::BoardReaderApp::do_resume(uint64_t timeout, uint64_t timestamp)
123 {
124  report_string_ = "";
125  external_request_status_ = fragment_receiver_ptr_->resume(timeout, timestamp);
126  if (!external_request_status_)
127  {
128  report_string_ = "Error resuming ";
129  report_string_.append(app_name + ".");
130  }
131 
132  boost::thread::attributes attrs;
133  attrs.set_stack_size(4096 * 2000); // 8 MB
134  fragment_processing_thread_ = boost::thread(attrs, boost::bind(&BoardReaderCore::process_fragments, fragment_receiver_ptr_.get()));
135  /*
136  fragment_processing_future_ =
137  std::async(std::launch::async, &BoardReaderCore::process_fragments,
138  fragment_receiver_ptr_.get());*/
139 
140  return external_request_status_;
141 }
142 
144 {
145  report_string_ = "";
146  external_request_status_ = fragment_receiver_ptr_->shutdown(timeout);
147  // 02-Jun-2018, ELF & KAB: it's very, very unlikely that the following call is needed,
148  // but just in case...
149  if (fragment_processing_thread_.joinable()) fragment_processing_thread_.join();
150  if (!external_request_status_)
151  {
152  report_string_ = "Error shutting down ";
153  report_string_.append(app_name + ".");
154  }
155  return external_request_status_;
156 }
157 
158 bool artdaq::BoardReaderApp::do_soft_initialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
159 {
160  report_string_ = "";
161  external_request_status_ = fragment_receiver_ptr_->soft_initialize(pset, timeout, timestamp);
162  if (!external_request_status_)
163  {
164  report_string_ = "Error soft-initializing ";
165  report_string_.append(app_name + " ");
166  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
167  }
168  return external_request_status_;
169 }
170 
171 bool artdaq::BoardReaderApp::do_reinitialize(fhicl::ParameterSet const& pset, uint64_t timeout, uint64_t timestamp)
172 {
173  external_request_status_ = fragment_receiver_ptr_->reinitialize(pset, timeout, timestamp);
174  if (!external_request_status_)
175  {
176  report_string_ = "Error reinitializing ";
177  report_string_.append(app_name + " ");
178  report_string_.append("with ParameterSet = \"" + pset.to_string() + "\".");
179  }
180  return external_request_status_;
181 }
182 
184 {
185  TLOG(TLVL_DEBUG) << "Booted state entry action called.";
186 
187  // the destruction of any existing BoardReaderCore has to happen in the
188  // Booted Entry action rather than the Initialized Exit action because the
189  // Initialized Exit action is only called after the "init" transition guard
190  // condition is executed.
191  fragment_receiver_ptr_.reset(nullptr);
192 }
193 
194 bool artdaq::BoardReaderApp::do_meta_command(std::string const& command, std::string const& arg)
195 {
196  external_request_status_ = fragment_receiver_ptr_->metaCommand(command, arg);
197  if (!external_request_status_)
198  {
199  report_string_ = "Error running meta-command on ";
200  report_string_.append(app_name + " ");
201  report_string_.append("with command = \"" + command + "\", arg = \"" + arg + "\".");
202  }
203  return external_request_status_;
204 }
205 
206 std::string artdaq::BoardReaderApp::report(std::string const& which) const
207 {
208  std::string resultString;
209 
210  // if all that is requested is the latest state change result, return it
211  if (which == "transition_status")
212  {
213  if (report_string_.length() > 0) { return report_string_; }
214  else
215  {
216  return "Success";
217  }
218  }
219 
222  //if (report_string_.length() > 0) {
223  // resultString.append("*** Overall status message:\r\n");
224  // resultString.append(report_string_ + "\r\n");
225  // resultString.append("*** Requested report response:\r\n");
226  //}
227 
228  // pass the request to the BoardReaderCore instance, if it's available
229  if (fragment_receiver_ptr_.get() != 0)
230  {
231  resultString.append(fragment_receiver_ptr_->report(which));
232  }
233  else
234  {
235  resultString.append("This BoardReader has not yet been initialized and ");
236  resultString.append("therefore can not provide reporting.");
237  }
238 
239  return resultString;
240 }
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.