artdaq_core  v3_06_00
SimpleMemoryReader.cc
1 #define TRACE_NAME "SimpleMemoryReader"
2 #include "artdaq-core/Core/SimpleMemoryReader.hh"
3 
4 #include <chrono> // for milliseconds
5 #include <cstddef> // for std::size_t
6 #include <iostream>
7 #include <string>
8 #include "tracemf.h" // TRACE
9 
10 namespace artdaq {
11 int SimpleMemoryReaderApp(int argc, char** argv)
12 {
13  try
14  {
15  size_t eec(0);
16  if (argc == 2)
17  {
18  std::istringstream ins(argv[1]); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
19  ins >> eec;
20  }
21  SimpleMemoryReader reader(0xA99, 0xB99, eec);
22  reader.run();
23  return 0;
24  }
25  catch (std::string const& msg)
26  {
27  std::cerr << "SimpleMemoryReaderApp failed: " << msg;
28  return 1;
29  }
30  catch (...)
31  {
32  return 1;
33  }
34 }
35 
37  SimpleMemoryReader(uint32_t shm_key, uint32_t broadcast_key, std::size_t eec)
38  : incoming_events_(new SharedMemoryEventReceiver(shm_key, broadcast_key))
39  , expectedEventCount_(eec)
40 {
41  TLOG(50) << "ctor done (after queue_.setReaderIsReady())";
42 }
43 
45 {
46  std::size_t eventsSeen = 0;
47  auto doPrint = getenv("VERBOSE_QUEUE_READING");
48  while (true)
49  {
50  bool keep_looping = true;
51  bool got_event = false;
52  while (keep_looping)
53  {
54  keep_looping = false;
55  got_event = incoming_events_->ReadyForRead();
56  if (!got_event)
57  {
58  TLOG(TLVL_INFO) << "InputFailure: Reading timed out in SharedMemoryReader::readNext()";
59  keep_looping = true;
60  }
61  }
62 
63  if (!got_event)
64  {
65  break;
66  }
67 
68  auto errflag = false;
69  auto evtHeader = incoming_events_->ReadHeader(errflag);
70  if (errflag)
71  {
72  break; // Buffer was changed out from under reader!
73  }
74  auto fragmentTypes = incoming_events_->GetFragmentTypes(errflag);
75  if (errflag)
76  {
77  break; // Buffer was changed out from under reader!
78  }
79  if (fragmentTypes.empty())
80  {
81  TLOG(TLVL_ERROR) << "Event has no Fragments! Aborting!";
82  incoming_events_->ReleaseBuffer();
83  break;
84  }
85  auto firstFragmentType = *fragmentTypes.begin();
86 
87  // We return false, indicating we're done reading, if:
88  // 1) we did not obtain an event, because we timed out and were
89  // configured NOT to keep trying after a timeout, or
90  // 2) the event we read was the end-of-data marker: a null
91  // pointer
92  if (!got_event || firstFragmentType == Fragment::EndOfDataFragmentType)
93  {
94  TLOG(TLVL_DEBUG) << "Received shutdown message, returning false";
95  incoming_events_->ReleaseBuffer();
96  break;
97  }
98 
99  ++eventsSeen;
100  RawEvent evt = RawEvent(*evtHeader);
101  if (doPrint != nullptr) { std::cout << evt << std::endl; }
102  incoming_events_->ReleaseBuffer();
103  }
104  if ((expectedEventCount_ != 0u) && eventsSeen != expectedEventCount_)
105  {
106  throw cet::exception("SimpleMemoryReader") // NOLINT(cert-err60-cpp)
107  << "Wrong number of events in SimpleMemoryReader ("
108  << eventsSeen << " != " << expectedEventCount_ << ").";
109  }
110 }
111 } // namespace artdaq
void run()
Run until a null pointer is popped off of the RawEventQueue. Throws an excpetion if expectedEventCoun...
static constexpr type_t EndOfDataFragmentType
Copy EndOfDataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:148
SharedMemoryEventReceiver can receive events (as written by SharedMemoryEventManager) from Shared Mem...
SimpleMemoryReader will continue to read RawEvent objects off the queue until it encounters a null po...
SimpleMemoryReader(uint32_t shm_key, uint32_t broadcast_key, std::size_t eec=0)
Constructs a SimpleMemoryReader.
int SimpleMemoryReaderApp(int argc, char **argv)
An application which pops items off a RawEventQueue using the SimpleMemoryReader. ...
RawEvent is the artdaq view of a generic event, containing a header and zero or more Fragments...
Definition: RawEvent.hh:97