Skip to content

Commit 494c3f1

Browse files
committed
[Concurrency] Fix races/overflows in TaskGroup implementation.
statusCompletePendingReadyWaiting(), offer(), and poll() did a one-off compare_exchange_strong which could fail if the group was concurrently cancelled. Put these into loops so that they are retried when needed. DiscardingTaskGroup creation passed the group result type as the task result type. waitAll() would then use the group result type when collecting task results. Since the task result type is always Void in this case, this would overflow the result buffer if the group result type was larger. This often works as it writes into the free space of the task allocator, but can crash if it happens to be at the end of a page or the group result type is particularly large. rdar://151663730
1 parent 94b40d1 commit 494c3f1

File tree

4 files changed

+195
-107
lines changed

4 files changed

+195
-107
lines changed

stdlib/public/Concurrency/DiscardingTaskGroup.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public func withDiscardingTaskGroup<GroupResult>(
8080
discardResults: true
8181
)
8282

83-
let _group = Builtin.createTaskGroupWithFlags(flags, GroupResult.self)
83+
let _group = Builtin.createTaskGroupWithFlags(flags, Void.self)
8484
var group = DiscardingTaskGroup(group: _group)
8585
defer { Builtin.destroyTaskGroup(_group) }
8686

@@ -108,7 +108,7 @@ public func _unsafeInheritExecutor_withDiscardingTaskGroup<GroupResult>(
108108
discardResults: true
109109
)
110110

111-
let _group = Builtin.createTaskGroupWithFlags(flags, GroupResult.self)
111+
let _group = Builtin.createTaskGroupWithFlags(flags, Void.self)
112112
var group = DiscardingTaskGroup(group: _group)
113113
defer { Builtin.destroyTaskGroup(_group) }
114114

@@ -347,7 +347,7 @@ public func withThrowingDiscardingTaskGroup<GroupResult>(
347347
discardResults: true
348348
)
349349

350-
let _group = Builtin.createTaskGroupWithFlags(flags, GroupResult.self)
350+
let _group = Builtin.createTaskGroupWithFlags(flags, Void.self)
351351
var group = ThrowingDiscardingTaskGroup<Error>(group: _group)
352352
defer { Builtin.destroyTaskGroup(_group) }
353353

@@ -378,7 +378,7 @@ public func _unsafeInheritExecutor_withThrowingDiscardingTaskGroup<GroupResult>(
378378
discardResults: true
379379
)
380380

381-
let _group = Builtin.createTaskGroupWithFlags(flags, GroupResult.self)
381+
let _group = Builtin.createTaskGroupWithFlags(flags, Void.self)
382382
var group = ThrowingDiscardingTaskGroup<Error>(group: _group)
383383
defer { Builtin.destroyTaskGroup(_group) }
384384

0 commit comments

Comments
 (0)