/ src / msg_queue.h
msg_queue.h
 1  #pragma once
 2  
 3  #include <atomic>
 4  
 5  // A simple queue. No locks, but only works with a single thread as producer and a single thread as
 6  // a consumer. Mutex up as needed.
 7  
 8  template <typename ElementType, size_t QueueSize>
 9  class MsgQueue {
10      ElementType queue_[QueueSize];
11      std::atomic_uint nextAdd_{0};
12      std::atomic_uint nextSend_{0};
13      std::atomic_uint pendingSends_{0};
14  
15  public:
16      MsgQueue() {}
17  
18      ElementType* GetNextAddMessage()
19      {
20          // if we are falling behind, bail
21          if (pendingSends_.load() >= QueueSize) {
22              return nullptr;
23          }
24          auto index = (nextAdd_++) % QueueSize;
25          return &queue_[index];
26      }
27      void CommitAdd() { ++pendingSends_; }
28  
29      bool HavePendingSends() const { return pendingSends_.load() != 0; }
30      ElementType* GetNextSendMessage()
31      {
32          auto index = (nextSend_++) % QueueSize;
33          return &queue_[index];
34      }
35      void CommitSend() { --pendingSends_; }
36  };