26 template <
typename Context>
28 auto* thread = context.getCurrentThread();
29 return thread ?
static_cast<void*
>(thread) :
static_cast<void*
>(&context);
39 m_pDispatchOwner(
nullptr),
40 m_bDispatching(
false),
41 m_bDeferredRemoval(
false) {}
43 void prepare(
void* event, uint64_t deadline,
void* target) {
47 m_Deadline = deadline;
49 m_pDispatchOwner =
nullptr;
50 m_bDeferredRemoval =
false;
57 uint64_t deadline()
const {
61 void* target()
const {
69 bool dispatching()
const {
70 return m_bDispatching;
73 bool deferredRemoval()
const {
74 return m_bDeferredRemoval;
84 m_pDispatchOwner =
nullptr;
85 m_bDispatching =
false;
86 m_bDeferredRemoval =
false;
93 void* m_pDispatchOwner;
95 bool m_bDeferredRemoval;
98 enum class RemovalDisposition {
106 RemovalDisposition disposition;
111 RtcAlarmQueue() : m_pFirst(nullptr), m_pLast(nullptr), m_pFree(nullptr) {}
113 Record* takeReusable() {
114 Record* record = m_pFree;
116 m_pFree = record->m_pNext;
117 record->m_pNext =
nullptr;
122 void add(Record* record) {
125 assert(record->m_pTarget);
127 assert(!record->m_bDispatching);
129 m_pLast->m_pNext = record;
136 Record* claimDue(uint64_t now,
void* owner) {
138 for (Record* record = m_pFirst; record; record = record->m_pNext) {
139 if (!record->m_bDispatching && record->m_Deadline <= now) {
140 record->m_bDispatching =
true;
141 record->m_pDispatchOwner = owner;
148 Removal removeFirst(
void* event,
void* owner) {
149 Record* previous =
nullptr;
150 for (Record* record = m_pFirst; record; record = record->m_pNext) {
151 if (record->m_pEvent != event) {
155 if (record->m_bDispatching) {
156 if (record->m_pDispatchOwner == owner) {
157 record->m_bDeferredRemoval =
true;
158 return {RemovalDisposition::SelfDeferred,
nullptr, record->m_Deadline};
160 return {RemovalDisposition::RemoteInFlight,
nullptr, record->m_Deadline};
163 const uint64_t deadline = record->m_Deadline;
164 unlink(previous, record);
165 return {RemovalDisposition::Removed, record, deadline};
167 return {RemovalDisposition::NotFound,
nullptr, 0};
170 Record* removeAllQueued(
void* event,
void* owner,
bool& remoteInFlight,
bool& selfDeferred) {
171 Record* removed =
nullptr;
172 Record* removedTail =
nullptr;
173 Record* previous =
nullptr;
174 Record* record = m_pFirst;
176 Record* next = record->m_pNext;
177 if (record->m_pEvent != event) {
182 if (record->m_bDispatching) {
183 if (record->m_pDispatchOwner == owner) {
184 record->m_bDeferredRemoval =
true;
187 remoteInFlight =
true;
194 unlink(previous, record);
195 record->m_pNext =
nullptr;
197 removedTail->m_pNext = record;
201 removedTail = record;
207 bool hasRemoteInFlight(
void* event,
void* owner)
const {
208 for (Record* record = m_pFirst; record; record = record->m_pNext) {
209 if (record->m_pEvent == event && record->m_bDispatching &&
210 record->m_pDispatchOwner != owner) {
217 void completeDispatch(Record* record) {
219 assert(record->m_bDispatching);
220 Record* previous =
nullptr;
221 Record* candidate = m_pFirst;
222 while (candidate && candidate != record) {
223 previous = candidate;
224 candidate = candidate->m_pNext;
226 assert(candidate == record);
227 unlink(previous, record);
231 void recycleList(Record* records) {
233 Record* next = records->m_pNext;
234 records->m_pNext =
nullptr;
240 Record* detachActive() {
241 Record* records = m_pFirst;
247 Record* detachFree() {
248 Record* records = m_pFree;
253 size_t activeCount()
const {
255 for (Record* record = m_pFirst; record; record = record->m_pNext) {
261 size_t freeCount()
const {
263 for (Record* record = m_pFree; record; record = record->m_pNext) {
270 void unlink(Record* previous, Record* record) {
272 previous->m_pNext = record->m_pNext;
274 m_pFirst = record->m_pNext;
276 if (m_pLast == record) {
279 record->m_pNext =
nullptr;
282 void recycle(Record* record) {
284 record->m_pNext = m_pFree;