otsdaq-mu2e-stm  5.02.01
ring_buffer.cc
1 // Include header
2 #include "ring_buffer.hh"
3 
4 // Add an item to the buffer
5 template<typename T>
6 void RingBuffer<T>::push(const std::shared_ptr<T>& item)
7 {
8  std::unique_lock<std::mutex> lock(mutex); // Lock for thread safety
9  cv_push.wait(lock,
10  [this]() { return stop || size < capacity; }); // Wait if buffer is full
11  if(stop)
12  return; // Exit if stop flag is set
13  buffer[head] = item; // Add item to buffer
14  head = (head + 1) % capacity; // Update head index
15  ++size; // Increment buffer size
16  cv_pop.notify_one(); // Notify consumers
17 }
18 
19 // Remove and return an item from the buffer
20 template<typename T>
21 std::shared_ptr<T> RingBuffer<T>::pop()
22 {
23  std::unique_lock<std::mutex> lock(mutex); // Lock for thread safety
24  cv_pop.wait(lock, [this]() { return stop || size > 0; }); // Wait if buffer is empty
25  if(size == 0)
26  return nullptr; // Return null if buffer is empty
27  auto item = buffer[tail]; // Retrieve item from buffer
28  tail = (tail + 1) % capacity; // Update tail index
29  --size; // Decrement buffer size
30  cv_push.notify_one(); // Notify producers
31  return item; // Return the item
32 }
33 
34 // Stop buffer operations
35 template<typename T>
37 {
38  {
39  std::lock_guard<std::mutex> lock(mutex); // Lock for thread safety
40  stop = true; // Set stop flag
41  }
42  cv_push.notify_all(); // Notify all waiting producers
43  cv_pop.notify_all(); // Notify all waiting consumers
44 }
45 
46 // Check if buffer is empty
47 template<typename T>
49 {
50  std::lock_guard<std::mutex> lock(mutex); // Lock for thread safety
51  return size == 0; // Return true if buffer size is zero
52 }
53 
54 template class RingBuffer<DataStruct>;