Skip to content

Commit 313165d

Browse files
committed
In debug builds, assert that tasks are complete during deallocation.
1 parent 5019190 commit 313165d

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

stdlib/public/Concurrency/TaskPrivate.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,12 @@ class alignas(2 * sizeof(void*)) ActiveTaskStatus {
280280
/// actor. This bit is cleared when a starts running on a thread, suspends
281281
/// or is completed.
282282
IsEnqueued = 0x1000,
283+
284+
#ifndef NDEBUG
285+
/// Task has been completed. This is purely used to enable an assertion
286+
/// that the task is completed when we destroy it.
287+
IsComplete = 0x2000,
288+
#endif
283289
};
284290

285291
#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION && SWIFT_POINTER_IS_4_BYTES
@@ -393,6 +399,20 @@ class alignas(2 * sizeof(void*)) ActiveTaskStatus {
393399
#endif
394400
}
395401

402+
#ifndef NDEBUG
403+
bool isComplete() const {
404+
return Flags & IsComplete;
405+
}
406+
407+
ActiveTaskStatus withComplete() const {
408+
#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
409+
return ActiveTaskStatus(Record, Flags | IsComplete, ExecutionLock);
410+
#else
411+
return ActiveTaskStatus(Record, Flags | IsComplete);
412+
#endif
413+
}
414+
#endif
415+
396416
/// Is there a lock on the linked list of status records?
397417
bool isStatusRecordLocked() const { return Flags & IsStatusRecordLocked; }
398418
ActiveTaskStatus withLockingRecord(TaskStatusRecord *lockRecord) const {
@@ -564,6 +584,9 @@ struct AsyncTask::PrivateStorage {
564584
auto newStatus = oldStatus.withRunning(false);
565585
newStatus = newStatus.withoutStoredPriorityEscalation();
566586
newStatus = newStatus.withoutEnqueued();
587+
#ifndef NDEBUG
588+
newStatus = newStatus.withComplete();
589+
#endif
567590

568591
// This can fail since the task can still get concurrently cancelled or
569592
// escalated.
@@ -650,6 +673,7 @@ retry:;
650673
while (true) {
651674
// We can get here from being suspended or being enqueued
652675
assert(!oldStatus.isRunning());
676+
assert(!oldStatus.isComplete());
653677

654678
#if SWIFT_CONCURRENCY_ENABLE_PRIORITY_ESCALATION
655679
// Task's priority is greater than the thread's - do a self escalation

0 commit comments

Comments
 (0)