artdaq_core  v3_00_03
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 <thread> // for sleep_for
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: "
29  << msg;
30  return 1;
31  }
32  catch (...)
33  {
34  return 1;
35  }
36  }
37 
39  SimpleMemoryReader(uint32_t shm_key,uint32_t broadcast_key, std::size_t eec) :
40  incoming_events_(new SharedMemoryEventReceiver(shm_key, broadcast_key))
41  , expectedEventCount_(eec)
42  {
43  TLOG_ARB(50, "SimpleMemoryReader") <<"ctor done (after queue_.setReaderIsReady())" << TLOG_ENDL;
44  }
45 
47  {
48  std::size_t eventsSeen = 0;
49  auto doPrint = getenv("VERBOSE_QUEUE_READING");
50  while (true)
51  {
52  bool keep_looping = true;
53  bool got_event = false;
54  while (keep_looping)
55  {
56  keep_looping = false;
57  got_event = incoming_events_->ReadyForRead();
58  if (!got_event)
59  {
60  TLOG_INFO("SharedMemoryReader")
61  << "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_ERROR("SharedMemoryReader") << "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_DEBUG("SharedMemoryReader") << "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