Skip to content

Commit 74fd8ce

Browse files
authored
Merge pull request #66103 from ktoso/pick-wip-discarding-error-task-leak
🍒[5.9][DiscardingTG] Undo pointer auth workaround; fix memory leaks
2 parents f3a3eef + 1a4c4c9 commit 74fd8ce

15 files changed

+412
-132
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,6 +2334,7 @@ class TaskCreateFlags : public FlagSet<size_t> {
23342334
Task_InheritContext = 11,
23352335
Task_EnqueueJob = 12,
23362336
Task_AddPendingGroupTaskUnconditionally = 13,
2337+
Task_IsDiscardingTask = 14,
23372338
};
23382339

23392340
explicit constexpr TaskCreateFlags(size_t bits) : FlagSet(bits) {}
@@ -2360,6 +2361,9 @@ class TaskCreateFlags : public FlagSet<size_t> {
23602361
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_AddPendingGroupTaskUnconditionally,
23612362
addPendingGroupTaskUnconditionally,
23622363
setAddPendingGroupTaskUnconditionally)
2364+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsDiscardingTask,
2365+
isDiscardingTask,
2366+
setIsDiscardingTask)
23632367
};
23642368

23652369
/// Flags for schedulable jobs.

stdlib/public/Concurrency/DiscardingTaskGroup.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,21 @@ public struct DiscardingTaskGroup {
171171
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
172172
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
173173
#endif
174-
public mutating func addTask<DiscardedResult>(
174+
public mutating func addTask(
175175
priority: TaskPriority? = nil,
176-
operation: __owned @Sendable @escaping () async -> DiscardedResult
176+
operation: __owned @Sendable @escaping () async -> Void
177177
) {
178178
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
179179
let flags = taskCreateFlags(
180180
priority: priority, isChildTask: true, copyTaskLocals: false,
181181
inheritContext: false, enqueueJob: false,
182-
addPendingGroupTaskUnconditionally: true
182+
addPendingGroupTaskUnconditionally: true, isDiscardingTask: true
183183
)
184184
#else
185185
let flags = taskCreateFlags(
186186
priority: priority, isChildTask: true, copyTaskLocals: false,
187187
inheritContext: false, enqueueJob: true,
188-
addPendingGroupTaskUnconditionally: true
188+
addPendingGroupTaskUnconditionally: true, isDiscardingTask: true
189189
)
190190
#endif
191191

@@ -206,9 +206,9 @@ public struct DiscardingTaskGroup {
206206
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
207207
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
208208
#endif
209-
public mutating func addTaskUnlessCancelled<DiscardedResult>(
209+
public mutating func addTaskUnlessCancelled(
210210
priority: TaskPriority? = nil,
211-
operation: __owned @Sendable @escaping () async -> DiscardedResult
211+
operation: __owned @Sendable @escaping () async -> Void
212212
) -> Bool {
213213
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
214214

@@ -220,13 +220,13 @@ public struct DiscardingTaskGroup {
220220
let flags = taskCreateFlags(
221221
priority: priority, isChildTask: true, copyTaskLocals: false,
222222
inheritContext: false, enqueueJob: false,
223-
addPendingGroupTaskUnconditionally: false
223+
addPendingGroupTaskUnconditionally: false, isDiscardingTask: true
224224
)
225225
#else
226226
let flags = taskCreateFlags(
227227
priority: priority, isChildTask: true, copyTaskLocals: false,
228228
inheritContext: false, enqueueJob: true,
229-
addPendingGroupTaskUnconditionally: false
229+
addPendingGroupTaskUnconditionally: false, isDiscardingTask: true
230230
)
231231
#endif
232232

@@ -237,13 +237,13 @@ public struct DiscardingTaskGroup {
237237
}
238238

239239
@_alwaysEmitIntoClient
240-
public mutating func addTask<DiscardedResult>(
241-
operation: __owned @Sendable @escaping () async -> DiscardedResult
240+
public mutating func addTask(
241+
operation: __owned @Sendable @escaping () async -> Void
242242
) {
243243
let flags = taskCreateFlags(
244244
priority: nil, isChildTask: true, copyTaskLocals: false,
245245
inheritContext: false, enqueueJob: true,
246-
addPendingGroupTaskUnconditionally: true
246+
addPendingGroupTaskUnconditionally: true, isDiscardingTask: true
247247
)
248248

249249
// Create the task in this group.
@@ -260,8 +260,8 @@ public struct DiscardingTaskGroup {
260260
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTaskUnlessCancelled(operation:)")
261261
#endif
262262
@_alwaysEmitIntoClient
263-
public mutating func addTaskUnlessCancelled<DiscardedResult>(
264-
operation: __owned @Sendable @escaping () async -> DiscardedResult
263+
public mutating func addTaskUnlessCancelled(
264+
operation: __owned @Sendable @escaping () async -> Void
265265
) -> Bool {
266266
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
267267
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
@@ -274,7 +274,7 @@ public struct DiscardingTaskGroup {
274274
let flags = taskCreateFlags(
275275
priority: nil, isChildTask: true, copyTaskLocals: false,
276276
inheritContext: false, enqueueJob: true,
277-
addPendingGroupTaskUnconditionally: false
277+
addPendingGroupTaskUnconditionally: false, isDiscardingTask: true
278278
)
279279

280280
// Create the task in this group.
@@ -547,15 +547,15 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
547547
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
548548
#endif
549549
@_alwaysEmitIntoClient
550-
public mutating func addTask<DiscardedResult>(
550+
public mutating func addTask(
551551
priority: TaskPriority? = nil,
552-
operation: __owned @Sendable @escaping () async throws -> DiscardedResult
552+
operation: __owned @Sendable @escaping () async throws -> Void
553553
) {
554554
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
555555
let flags = taskCreateFlags(
556556
priority: priority, isChildTask: true, copyTaskLocals: false,
557557
inheritContext: false, enqueueJob: true,
558-
addPendingGroupTaskUnconditionally: true
558+
addPendingGroupTaskUnconditionally: true, isDiscardingTask: true
559559
)
560560

561561
// Create the task in this group.
@@ -569,9 +569,9 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
569569
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model", renamed: "addTask(operation:)")
570570
#endif
571571
@_alwaysEmitIntoClient
572-
public mutating func addTaskUnlessCancelled<DiscardedResult>(
572+
public mutating func addTaskUnlessCancelled(
573573
priority: TaskPriority? = nil,
574-
operation: __owned @Sendable @escaping () async throws -> DiscardedResult
574+
operation: __owned @Sendable @escaping () async throws -> Void
575575
) -> Bool {
576576
#if compiler(>=5.5) && $BuiltinCreateAsyncTaskInGroup
577577
let canAdd = _taskGroupAddPendingTask(group: _group, unconditionally: false)
@@ -584,7 +584,7 @@ public struct ThrowingDiscardingTaskGroup<Failure: Error> {
584584
let flags = taskCreateFlags(
585585
priority: priority, isChildTask: true, copyTaskLocals: false,
586586
inheritContext: false, enqueueJob: true,
587-
addPendingGroupTaskUnconditionally: false
587+
addPendingGroupTaskUnconditionally: false, isDiscardingTask: true
588588
)
589589

590590
// Create the task in this group.

stdlib/public/Concurrency/Task.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ static AsyncTaskAndContext swift_task_create_commonImpl(
940940
// be is the final hop. Store a signed null instead.
941941
initialContext->Parent = nullptr;
942942

943+
// FIXME: add discarding flag
943944
concurrency::trace::task_create(
944945
task, parent, group, asyncLet,
945946
static_cast<uint8_t>(task->Flags.getPriority()),
@@ -1060,21 +1061,40 @@ void swift::swift_task_run_inline(OpaqueValue *result, void *closureAFP,
10601061

10611062
SWIFT_CC(swift)
10621063
AsyncTaskAndContext swift::swift_task_create(
1063-
size_t taskCreateFlags,
1064+
size_t rawTaskCreateFlags,
10641065
TaskOptionRecord *options,
10651066
const Metadata *futureResultType,
10661067
void *closureEntry, HeapObject *closureContext) {
1067-
FutureAsyncSignature::FunctionType *taskEntry;
1068-
size_t initialContextSize;
1069-
std::tie(taskEntry, initialContextSize) =
1068+
TaskCreateFlags taskCreateFlags(rawTaskCreateFlags);
1069+
1070+
if (taskCreateFlags.isDiscardingTask()) {
1071+
ThinNullaryAsyncSignature::FunctionType *taskEntry;
1072+
size_t initialContextSize;
1073+
1074+
std::tie(taskEntry, initialContextSize) =
10701075
getAsyncClosureEntryPointAndContextSize<
1071-
FutureAsyncSignature,
1072-
SpecialPointerAuthDiscriminators::AsyncFutureFunction>(closureEntry);
1076+
ThinNullaryAsyncSignature,
1077+
SpecialPointerAuthDiscriminators::AsyncThinNullaryFunction>(closureEntry);
1078+
1079+
return swift_task_create_common(
1080+
rawTaskCreateFlags, options, futureResultType,
1081+
reinterpret_cast<TaskContinuationFunction *>(taskEntry), closureContext,
1082+
initialContextSize);
10731083

1074-
return swift_task_create_common(
1075-
taskCreateFlags, options, futureResultType,
1076-
reinterpret_cast<TaskContinuationFunction *>(taskEntry), closureContext,
1077-
initialContextSize);
1084+
} else {
1085+
FutureAsyncSignature::FunctionType *taskEntry;
1086+
size_t initialContextSize;
1087+
1088+
std::tie(taskEntry, initialContextSize) =
1089+
getAsyncClosureEntryPointAndContextSize<
1090+
FutureAsyncSignature,
1091+
SpecialPointerAuthDiscriminators::AsyncFutureFunction>(closureEntry);
1092+
1093+
return swift_task_create_common(
1094+
rawTaskCreateFlags, options, futureResultType,
1095+
reinterpret_cast<TaskContinuationFunction *>(taskEntry), closureContext,
1096+
initialContextSize);
1097+
}
10781098
}
10791099

10801100
#ifdef __ARM_ARCH_7K__

stdlib/public/Concurrency/Task.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ extension Task where Failure == Error {
200200
let flags = taskCreateFlags(priority: priority, isChildTask: false,
201201
copyTaskLocals: true, inheritContext: true,
202202
enqueueJob: false,
203-
addPendingGroupTaskUnconditionally: false)
203+
addPendingGroupTaskUnconditionally: false,
204+
isDiscardingTask: false)
204205
let (task, _) = Builtin.createAsyncTask(flags, work)
205206
_startTaskOnMainActor(task)
206207
return Task<Success, Error>(task)
@@ -222,7 +223,8 @@ extension Task where Failure == Never {
222223
let flags = taskCreateFlags(priority: priority, isChildTask: false,
223224
copyTaskLocals: true, inheritContext: true,
224225
enqueueJob: false,
225-
addPendingGroupTaskUnconditionally: false)
226+
addPendingGroupTaskUnconditionally: false,
227+
isDiscardingTask: false)
226228
let (task, _) = Builtin.createAsyncTask(flags, work)
227229
_startTaskOnMainActor(task)
228230
return Task(task)
@@ -503,7 +505,8 @@ struct JobFlags {
503505
func taskCreateFlags(
504506
priority: TaskPriority?, isChildTask: Bool, copyTaskLocals: Bool,
505507
inheritContext: Bool, enqueueJob: Bool,
506-
addPendingGroupTaskUnconditionally: Bool
508+
addPendingGroupTaskUnconditionally: Bool,
509+
isDiscardingTask: Bool
507510
) -> Int {
508511
var bits = 0
509512
bits |= (bits & ~0xFF) | Int(priority?.rawValue ?? 0)
@@ -522,6 +525,9 @@ func taskCreateFlags(
522525
if addPendingGroupTaskUnconditionally {
523526
bits |= 1 << 13
524527
}
528+
if isDiscardingTask {
529+
bits |= 1 << 14
530+
}
525531
return bits
526532
}
527533

@@ -573,7 +579,8 @@ extension Task where Failure == Never {
573579
let flags = taskCreateFlags(
574580
priority: priority, isChildTask: false, copyTaskLocals: true,
575581
inheritContext: true, enqueueJob: true,
576-
addPendingGroupTaskUnconditionally: false)
582+
addPendingGroupTaskUnconditionally: false,
583+
isDiscardingTask: false)
577584

578585
// Create the asynchronous task.
579586
let (task, _) = Builtin.createAsyncTask(flags, operation)
@@ -633,8 +640,8 @@ extension Task where Failure == Error {
633640
let flags = taskCreateFlags(
634641
priority: priority, isChildTask: false, copyTaskLocals: true,
635642
inheritContext: true, enqueueJob: true,
636-
addPendingGroupTaskUnconditionally: false
637-
)
643+
addPendingGroupTaskUnconditionally: false,
644+
isDiscardingTask: false)
638645

639646
// Create the asynchronous task future.
640647
let (task, _) = Builtin.createAsyncTask(flags, operation)
@@ -692,7 +699,8 @@ extension Task where Failure == Never {
692699
let flags = taskCreateFlags(
693700
priority: priority, isChildTask: false, copyTaskLocals: false,
694701
inheritContext: false, enqueueJob: true,
695-
addPendingGroupTaskUnconditionally: false)
702+
addPendingGroupTaskUnconditionally: false,
703+
isDiscardingTask: false)
696704

697705
// Create the asynchronous task future.
698706
let (task, _) = Builtin.createAsyncTask(flags, operation)
@@ -751,8 +759,8 @@ extension Task where Failure == Error {
751759
let flags = taskCreateFlags(
752760
priority: priority, isChildTask: false, copyTaskLocals: false,
753761
inheritContext: false, enqueueJob: true,
754-
addPendingGroupTaskUnconditionally: false
755-
)
762+
addPendingGroupTaskUnconditionally: false,
763+
isDiscardingTask: false)
756764

757765
// Create the asynchronous task future.
758766
let (task, _) = Builtin.createAsyncTask(flags, operation)

0 commit comments

Comments
 (0)