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