artdaq_core  v3_01_04
SimpleMemoryReader.cc
1 #include "artdaq-core/Core/SimpleMemoryReader.hh"
2 
3 #include <chrono> // for milliseconds
4 #include <cstddef> // for std::size_t
5 #include <iostream>
6 #include <string>
7 #include "tracemf.h" // TRACE
8 
9 #undef TRACE_NAME
10 #define TRACE_NAME "SimpleMemoryReader"
11 
12 namespace artdaq
13 {
14  int SimpleMemoryReaderApp(int argc, char** argv)
15  {
16  try
17  {
18  size_t eec(0);
19  if (argc == 2)
20  {
21  std::istringstream ins(argv[1]);
22  ins >> eec;
23  }
24  SimpleMemoryReader reader(0xA99, 0xB99, eec);
25  reader.run();
26  return 0;
27  }
28  catch (std::string const& msg)
29  {
30  std::cerr << "SimpleMemoryReaderApp failed: " << msg;
31  return 1;
32  }
33  catch (...)
34  {
35  return 1;
36  }
37  }
38 
40  SimpleMemoryReader(uint32_t shm_key, uint32_t broadcast_key, std::size_t eec) :
41  incoming_events_(new SharedMemoryEventReceiver(shm_key, broadcast_key))
42  , expectedEventCount_(eec)
43  {
44  TLOG(50) << "ctor done (after queue_.setReaderIsReady())" << TLOG_ENDL;
45  }
46 
48  {
49  std::size_t eventsSeen = 0;
50  auto doPrint = getenv("VERBOSE_QUEUE_READING");
51  while (true)
52  {
53  bool keep_looping = true;
54  bool got_event = false;
55  while (keep_looping)
56  {
57  keep_looping = false;
58  got_event = incoming_events_->ReadyForRead();
59  if (!got_event)
60  {
61  TLOG(TLVL_INFO) << "InputFailure: Reading timed out in SharedMemoryReader::readNext()" << TLOG_ENDL;
62  keep_looping = true;
63  }
64  }
65 
66  if (!got_event) break;
67 
68  auto errflag = false;
69  auto evtHeader = incoming_events_->ReadHeader(errflag);
70  if (errflag) break; // Buffer was changed out from under reader!
71  auto fragmentTypes = incoming_events_->GetFragmentTypes(errflag);
72  if (errflag) break; // Buffer was changed out from under reader!
73  if (fragmentTypes.size() == 0)
74  {
75  TLOG(TLVL_ERROR) << "Event has no Fragments! Aborting!" << TLOG_ENDL;
76  incoming_events_->ReleaseBuffer();
77  break;
78  }
79  auto firstFragmentType = *fragmentTypes.begin();
80 
81  // We return false, indicating we're done reading, if:
82  // 1) we did not obtain an event, because we timed out and were
83  // configured NOT to keep trying after a timeout, or
84  // 2) the event we read was the end-of-data marker: a null
85  // pointer
86  if (!got_event || firstFragmentType == Fragment::EndOfDataFragmentType)
87  {
88  TLOG(TLVL_DEBUG) << "Received shutdown message, returning false" << TLOG_ENDL;
89  incoming_events_->ReleaseBuffer();
90  break;
91  }
92 
93  ++eventsSeen;
94  RawEvent evt = RawEvent(*evtHeader);
95  if (doPrint) { std::cout << evt << std::endl; }
96  incoming_events_->ReleaseBuffer();
97 
98  }
99  if (expectedEventCount_ && eventsSeen != expectedEventCount_)
100  {
101  std::ostringstream os;
102  os << "Wrong number of events in SimpleMemoryReader ("
103  << eventsSeen << " != " << expectedEventCount_ << ").\n";
104  throw os.str();
105  }
106  }
107 }
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:147
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:64