UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ThreadSafeIntrusiveQueue.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Misc/ScopeLock.h"
8
9namespace UE::IoStore
10{
11
17template<typename T>
19{
20public:
21 void Enqueue(T* Request)
22 {
23 check(Request->NextRequest == nullptr);
24 FScopeLock _(&CriticalSection);
25
26 if (Tail)
27 {
28 Tail->NextRequest = Request;
29 }
30 else
31 {
32 check(Head == nullptr);
33 Head = Request;
34 }
35
36 Tail = Request;
37
38 ++ListNum;
39 }
40
41 void EnqueueByPriority(T* Request)
42 {
43 FScopeLock _(&CriticalSection);
44 EnqueueByPriorityInternal(Request);
45
46 ++ListNum;
47 }
48
50 {
51 FScopeLock _(&CriticalSection);
52
53 if (NumToRemove <= 0 || ListNum == 0)
54 {
55 return nullptr;
56 }
57 else if (NumToRemove == MAX_int32)
58 {
59 T* Requests = Head;
60 Head = Tail = nullptr;
61
62 ListNum = 0;
63
64 return Requests;
65 }
66 else
67 {
68 int32 NumRemoved = 1;
69 T* Requests = Head;
70 while(NumRemoved < NumToRemove && Requests->NextRequest != nullptr)
71 {
72 Requests = Requests->NextRequest;
73 NumRemoved++;
74 }
75
76 // Store the new head of the list for later
77 T* NewHead = Requests->NextRequest;
78
79 // Break off the subsection we are returning
80 Requests->NextRequest = nullptr;
81
82 // Clear the tail if the entire list was dequeued
83 if (Tail == Requests)
84 {
85 Tail = nullptr;
86 }
87
88 Swap(Head, NewHead);
89 ListNum -= NumRemoved;
90
91 return NewHead;
92 }
93
94
95 }
96
97 void Reprioritize(T* Request, int32 NewPriority)
98 {
99 check(Request != nullptr);
100
101 // Switch to double linked list/array if this gets too expensive
102 FScopeLock _(&CriticalSection);
103
104 Request->Priority = NewPriority;
105 if (RemoveInternal(Request))
106 {
107 EnqueueByPriorityInternal(Request);
108 }
109 }
110
111 int32 Num() const
112 {
113 FScopeLock _(&CriticalSection);
114 return ListNum;
115 }
116
117private:
118 void EnqueueByPriorityInternal(T* Request)
119 {
120 check(Request->NextRequest == nullptr);
121
122 if (Head == nullptr || Request->Priority > Head->Priority)
123 {
124 if (Head == nullptr)
125 {
126 check(Tail == nullptr);
127 Tail = Request;
128 }
129
130 Request->NextRequest = Head;
131 Head = Request;
132 }
133 else if (Request->Priority <= Tail->Priority)
134 {
135 check(Tail != nullptr);
136 Tail->NextRequest = Request;
137 Tail = Request;
138 }
139 else
140 {
141 // NOTE: This can get expensive if the queue gets too long, might be better to have x number of bucket(s)
142 TRACE_CPUPROFILER_EVENT_SCOPE(IasBackend::EnqueueByPriority);
143 T* It = Head;
144 while (It->NextRequest != nullptr && Request->Priority <= It->NextRequest->Priority)
145 {
146 It = It->NextRequest;
147 }
148
149 Request->NextRequest = It->NextRequest;
150 It->NextRequest = Request;
151 }
152 }
153
154 bool RemoveInternal(T* Request)
155 {
156 check(Request != nullptr);
157 if (Head == nullptr)
158 {
159 check(Tail == nullptr);
160 return false;
161 }
162
163 if (Head == Request)
164 {
165 Head = Request->NextRequest;
166 if (Tail == Request)
167 {
168 check(Head == nullptr);
169 Tail = nullptr;
170 }
171
172 Request->NextRequest = nullptr;
173 return true;
174 }
175 else
176 {
177 T* It = Head;
178 while (It->NextRequest && It->NextRequest != Request)
179 {
180 It = It->NextRequest;
181 }
182
183 if (It->NextRequest == Request)
184 {
185 It->NextRequest = It->NextRequest->NextRequest;
186 Request->NextRequest = nullptr;
187 if (Tail == Request)
188 {
189 Tail = It;
190 }
191 return true;
192 }
193 }
194
195 return false;
196 }
197
198 mutable FCriticalSection CriticalSection;
199
200 T* Head = nullptr;
201 T* Tail = nullptr;
202
203 int32 ListNum = 0;
204};
205
206} //namespace UE::IoStore
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
#define MAX_int32
Definition NumericLimits.h:25
Definition ScopeLock.h:141
Definition ThreadSafeIntrusiveQueue.h:19
void EnqueueByPriority(T *Request)
Definition ThreadSafeIntrusiveQueue.h:41
T * Dequeue(int32 NumToRemove=MAX_int32)
Definition ThreadSafeIntrusiveQueue.h:49
int32 Num() const
Definition ThreadSafeIntrusiveQueue.h:111
void Reprioritize(T *Request, int32 NewPriority)
Definition ThreadSafeIntrusiveQueue.h:97
void Enqueue(T *Request)
Definition ThreadSafeIntrusiveQueue.h:21
NO_LOGGING.
Definition Client.h:20