artdaq_core  v3_05_07
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]);
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) break;
64 
65  auto errflag = false;
66  auto evtHeader = incoming_events_->ReadHeader(errflag);
67  if (errflag) break; // Buffer was changed out from under reader!
68  auto fragmentTypes = incoming_events_->GetFragmentTypes(errflag);
69  if (errflag) break; // Buffer was changed out from under reader!
70  if (fragmentTypes.size() == 0)
71  {
72  TLOG(TLVL_ERROR) << "Event has no Fragments! Aborting!";
73  incoming_events_->ReleaseBuffer();
74  break;
75  }
76  auto firstFragmentType = *fragmentTypes.begin();
77 
78  // We return false, indicating we're done reading, if:
79  // 1) we did not obtain an event, because we timed out and were
80  // configured NOT to keep trying after a timeout, or
81  // 2) the event we read was the end-of-data marker: a null
82  // pointer
83  if (!got_event || firstFragmentType == Fragment::EndOfDataFragmentType)
84  {
85  TLOG(TLVL_DEBUG) << "Received shutdown message, returning false";
86  incoming_events_->ReleaseBuffer();
87  break;
88  }
89 
90  ++eventsSeen;
91  RawEvent evt = RawEvent(*evtHeader);
92  if (doPrint) { std::cout << evt << std::endl; }
93  incoming_events_->ReleaseBuffer();
94  }
95  if (expectedEventCount_ && eventsSeen != expectedEventCount_)
96  {
97  std::ostringstream os;
98  os << "Wrong number of events in SimpleMemoryReader ("
99  << eventsSeen << " != " << expectedEventCount_ << ").\n";
100  throw os.str();
101  }
102 }
103 } // namespace artdaq
void run()
Run until a null pointer is popped off of the RawEventQueue. Throws an excpetion if expectedEventCoun...
SimpleMemoryReader(uint32_t shm_key, uint32_t broadcast_key, std::size_t expectedEventCount=0)
Constructs a SimpleMemoryReader.
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...
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:66