artdaq_core  v3_01_02
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 namespace artdaq
10 {
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: "
28  << 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_ARB(50, "SimpleMemoryReader") <<"ctor done (after queue_.setReaderIsReady())" << TLOG_ENDL;
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_INFO("SharedMemoryReader")
60  << "InputFailure: Reading timed out in SharedMemoryReader::readNext()" << TLOG_ENDL;
61  keep_looping = true;
62  }
63  }
64 
65  if (!got_event) break;
66 
67  auto errflag = false;
68  auto evtHeader = incoming_events_->ReadHeader(errflag);
69  if (errflag) break; // Buffer was changed out from under reader!
70  auto fragmentTypes = incoming_events_->GetFragmentTypes(errflag);
71  if (errflag) break; // Buffer was changed out from under reader!
72  if (fragmentTypes.size() == 0)
73  {
74  TLOG_ERROR("SharedMemoryReader") << "Event has no Fragments! Aborting!" << TLOG_ENDL;
75  incoming_events_->ReleaseBuffer();
76  break;
77  }
78  auto firstFragmentType = *fragmentTypes.begin();
79 
80  // We return false, indicating we're done reading, if:
81  // 1) we did not obtain an event, because we timed out and were
82  // configured NOT to keep trying after a timeout, or
83  // 2) the event we read was the end-of-data marker: a null
84  // pointer
85  if (!got_event || firstFragmentType == Fragment::EndOfDataFragmentType)
86  {
87  TLOG_DEBUG("SharedMemoryReader") << "Received shutdown message, returning false" << TLOG_ENDL;
88  incoming_events_->ReleaseBuffer();
89  break;
90  }
91 
92  ++eventsSeen;
93  RawEvent evt = RawEvent(*evtHeader);
94  if (doPrint) { std::cout << evt << std::endl; }
95  incoming_events_->ReleaseBuffer();
96 
97  }
98  if (expectedEventCount_ && eventsSeen != expectedEventCount_)
99  {
100  std::ostringstream os;
101  os << "Wrong number of events in SimpleMemoryReader ("
102  << eventsSeen << " != " << expectedEventCount_ << ").\n";
103  throw os.str();
104  }
105  }
106 }
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