UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Queue.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5
6#include <atomic>
7#include <utility>
8
9namespace uLang
10{
11
18
22// TODO: (yiliang.siew) Allow for custom allocators as the rest of `uLang` does.
23// TODO: (yiliang.siew) See if some of the memory ordering requirements can be relaxed. For now
24// since it guarantees an `MFENCE` instruction on x86-64 arch. Unreal issues a `_mm_sfence` intrinsic,
25// which I'm not sure if I can guarantee via `std::atomic`.
26template <typename InElementType, EQueueMode Mode = EQueueMode::SingleProducerSingleConsumer>
28{
29public:
31 {
32 Head = Tail = new TNode();
33 }
34
36 {
37 while (Tail != nullptr)
38 {
39 TNode* Node = Tail;
40 Tail = Tail->Next;
41 delete Node;
42 }
43 }
44
53 {
54 TNode* NewNode = new TNode(InElement);
55 if (NewNode == nullptr)
56 {
57 return false;
58 }
59 TNode* OldHead;
61 {
62 OldHead = std::atomic_exchange_explicit(&Head, NewNode, std::memory_order_seq_cst);
63 std::atomic_exchange_explicit(&OldHead->Next, NewNode, std::memory_order_seq_cst);
64 }
65 else
66 {
67 OldHead = Head;
68 Head = NewNode;
69 std::atomic_thread_fence(std::memory_order_seq_cst);
70 OldHead->Next = NewNode;
71 }
72
73 return true;
74 }
75
77 {
78 TNode* NewNode = new TNode(InElement);
79 if (NewNode == nullptr)
80 {
81 return false;
82 }
83 TNode* OldHead;
85 {
86 OldHead = std::atomic_exchange_explicit(&Head, NewNode, std::memory_order_seq_cst);
87 std::atomic_exchange_explicit(&OldHead->Next, NewNode, std::memory_order_seq_cst);
88 }
89 else
90 {
91 OldHead = Head;
92 Head = NewNode;
93 std::atomic_thread_fence(std::memory_order_seq_cst);
94 OldHead->Next = NewNode;
95 }
96
97 return true;
98 }
99
108 {
109 TNode* Popped = Tail->Next;
110 if (Popped == nullptr)
111 {
112 return false;
113 }
114 OutElement = std::move(Popped->Element);
115 TNode* OldTail = Tail;
116 Tail = Popped;
117 Tail->Element = InElementType();
118 delete OldTail;
119
120 return true;
121 }
127 bool Pop()
128 {
129 TNode* Popped = Tail->Next;
130 if (Popped == nullptr)
131 {
132 return false;
133 }
134 TNode* OldTail = Tail;
135 Tail = Popped;
136 Tail->Element = InElementType();
137 delete OldTail;
138
139 return true;
140 }
141
145 void Empty()
146 {
147 while (Pop())
148 {
149 ;
150 }
151 }
152
158 bool IsEmpty()
159 {
160 return (Tail->Next.load() == nullptr);
161 }
162
163private:
165 struct TNode
166 {
167 TNode() : Next(nullptr)
168 {}
169
170 explicit TNode(const InElementType& InElement) : Next(nullptr), Element(InElement)
171 {}
172
174 explicit TNode(const InElementType&& InElement) : Next(nullptr), Element(std::move(InElement))
175 {}
176
177 std::atomic<TNode*> Next;
179 };
180
182 std::atomic<TNode*> Head;
183
185 TNode* Tail;
186
187protected:
189 TQueueG(const TQueueG&) = delete;
190
192 TQueueG& operator=(const TQueueG&) = delete;
193};
194
196template <typename InElementType>
198
200template <typename InElementType>
202
203} // namespace uLang
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition Queue.h:28
TQueueG & operator=(const TQueueG &)=delete
bool IsEmpty()
Definition Queue.h:158
bool Enqueue(const InElementType &InElement)
Definition Queue.h:52
bool Pop()
Definition Queue.h:127
void Empty()
Definition Queue.h:145
TQueueG()
Definition Queue.h:30
bool Enqueue(const InElementType &&InElement)
Definition Queue.h:76
TQueueG(const TQueueG &)=delete
bool Dequeue(InElementType &OutElement)
Definition Queue.h:107
~TQueueG()
Definition Queue.h:35
@ Element
Definition Visu.h:18
Definition VVMEngineEnvironment.h:23
EQueueMode
Concurrent queue modes.
Definition Queue.h:14
Definition VstNode.h:150