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 };