30class MpscQueue :
public NonCopyable
34 : head_(
new BufferNode), tail_(head_.load(std::memory_order_relaxed))
43 BufferNode *front = head_.load(std::memory_order_relaxed);
55 BufferNode *node{
new BufferNode(std::move(input))};
56 BufferNode *prevhead{head_.exchange(node, std::memory_order_acq_rel)};
57 prevhead->next_.store(node, std::memory_order_release);
61 BufferNode *node{
new BufferNode(input)};
62 BufferNode *prevhead{head_.exchange(node, std::memory_order_acq_rel)};
63 prevhead->next_.store(node, std::memory_order_release);
75 BufferNode *tail = tail_.load(std::memory_order_relaxed);
76 BufferNode *next = tail->next_.load(std::memory_order_acquire);
82 output = std::move(*(next->dataPtr_));
83 delete next->dataPtr_;
84 tail_.store(next, std::memory_order_release);
91 BufferNode *tail = tail_.load(std::memory_order_relaxed);
92 BufferNode *next = tail->next_.load(std::memory_order_acquire);
93 return next ==
nullptr;
99 BufferNode() =
default;
100 BufferNode(
const T &data) : dataPtr_(new T(data))
103 BufferNode(T &&data) : dataPtr_(new T(std::move(data)))
107 std::atomic<BufferNode *> next_{
nullptr};
110 std::atomic<BufferNode *> head_;
111 std::atomic<BufferNode *> tail_;