trantor
Non-blocking I/O cross-platform TCP network library, using C++14
Loading...
Searching...
No Matches
LockFreeQueue.h
Go to the documentation of this file.
1
14
15#pragma once
17#include <atomic>
18#include <type_traits>
19#include <memory>
20#include <assert.h>
21namespace trantor
22{
29template <typename T>
30class MpscQueue : public NonCopyable
31{
32 public:
33 MpscQueue()
34 : head_(new BufferNode), tail_(head_.load(std::memory_order_relaxed))
35 {
36 }
37 ~MpscQueue()
38 {
39 T output;
40 while (this->dequeue(output))
41 {
42 }
43 BufferNode *front = head_.load(std::memory_order_relaxed);
44 delete front;
45 }
46
53 void enqueue(T &&input)
54 {
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);
58 }
59 void enqueue(const T &input)
60 {
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);
64 }
65
73 bool dequeue(T &output)
74 {
75 BufferNode *tail = tail_.load(std::memory_order_relaxed);
76 BufferNode *next = tail->next_.load(std::memory_order_acquire);
77
78 if (next == nullptr)
79 {
80 return false;
81 }
82 output = std::move(*(next->dataPtr_));
83 delete next->dataPtr_;
84 tail_.store(next, std::memory_order_release);
85 delete tail;
86 return true;
87 }
88
89 bool empty()
90 {
91 BufferNode *tail = tail_.load(std::memory_order_relaxed);
92 BufferNode *next = tail->next_.load(std::memory_order_acquire);
93 return next == nullptr;
94 }
95
96 private:
97 struct BufferNode
98 {
99 BufferNode() = default;
100 BufferNode(const T &data) : dataPtr_(new T(data))
101 {
102 }
103 BufferNode(T &&data) : dataPtr_(new T(std::move(data)))
104 {
105 }
106 T *dataPtr_;
107 std::atomic<BufferNode *> next_{nullptr};
108 };
109
110 std::atomic<BufferNode *> head_;
111 std::atomic<BufferNode *> tail_;
112};
113
114} // namespace trantor
bool dequeue(T &output)
Get a item from the queue.
Definition LockFreeQueue.h:73
void enqueue(T &&input)
Put a item into the queue.
Definition LockFreeQueue.h:53
Definition EventLoop.h:34