Skip to content

Commit 9162d40

Browse files
committed
+task Implement Task.currentPriority
cleanups
1 parent 35acd40 commit 9162d40

File tree

4 files changed

+114
-10
lines changed

4 files changed

+114
-10
lines changed

stdlib/public/Concurrency/TaskGroup.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,23 @@ extension Task {
7373
// Set up the job flags for a new task.
7474
var groupFlags = JobFlags()
7575
groupFlags.kind = .task // TODO: .taskGroup?
76-
groupFlags.priority = .default // TODO: parent's priority // await Task.currentPriority()
76+
groupFlags.priority = await Task.currentPriority()
7777
groupFlags.isFuture = true
78+
groupFlags.isChildTask = true
7879

7980
// 1. Prepare the Group task
8081
// FIXME: do we have to rather prepare it inside the task we spawn; and yield it back along with the result instead?
8182
var group = Task.Group<TaskResult>(parentTask: parent)
8283

8384
let (groupTask, context) =
84-
Builtin.createAsyncTaskFuture(groupFlags.bits, nil) { () async throws -> BodyResult in
85-
let got = await try body(&group)
86-
return got
85+
Builtin.createAsyncTaskFuture(groupFlags.bits, parent) { () async throws -> BodyResult in
86+
await try body(&group)
8787
}
8888
let groupHandle = Handle<BodyResult>(task: groupTask)
8989

9090
// 2.0) Run the task!
91-
DispatchQueue.global(priority: .default).async {
92-
groupHandle.run() // TODO: this synchronously runs
91+
DispatchQueue.global(priority: .default).async { // TODO: use executors when they land
92+
groupHandle.run()
9393
}
9494

9595
// 2.1) ensure that if we fail and exit by throwing we will cancel all tasks,

test/Concurrency/Runtime/async_task_group_basic.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extension DispatchQueue {
2020
}
2121

2222
@available(*, deprecated, message: "This is a temporary hack")
23+
@discardableResult
2324
func launch<R>(operation: @escaping () async -> R) -> Task.Handle<R> {
2425
let handle = Task.runDetached(operation: operation)
2526

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -enable-experimental-concurrency) | %FileCheck %s --dump-input always
2+
// REQUIRES: executable_test
3+
// REQUIRES: concurrency
4+
// REQUIRES: OS=macosx
5+
6+
import Dispatch
7+
8+
// ==== ------------------------------------------------------------------------
9+
// MARK: "Infrastructure" for the tests
10+
11+
extension DispatchQueue {
12+
func async<R>(operation: @escaping () async -> R) -> Task.Handle<R> {
13+
let handle = Task.runDetached(operation: operation)
14+
15+
// Run the task
16+
_ = { self.async { handle.run() } }() // force invoking the non-async version
17+
18+
return handle
19+
}
20+
}
21+
22+
@available(*, deprecated, message: "This is a temporary hack")
23+
@discardableResult
24+
func launch<R>(operation: @escaping () async -> R) -> Task.Handle<R> {
25+
let handle = Task.runDetached(operation: operation)
26+
27+
// Run the task
28+
_ = DispatchQueue.global(priority: .default).async { handle.run() }
29+
30+
return handle
31+
}
32+
33+
// ==== ------------------------------------------------------------------------
34+
// MARK: Tests
35+
36+
func test_taskGroup_cancel_internally_afterOne() {
37+
let taskHandle = launch { () async -> Int in
38+
return await try! Task.withGroup(resultType: Int.self) { (group) async -> Int in
39+
40+
func submit(_ n: Int) async {
41+
await group.add {
42+
do {
43+
await try Task.checkCancellation()
44+
print("submitted: \(n)")
45+
return n
46+
} catch {
47+
print("submit failed: \(error)")
48+
throw error
49+
}
50+
}
51+
}
52+
53+
func pull() async -> Result<Int, Error>? {
54+
do {
55+
if let r = await try group.next() {
56+
return .success(r)
57+
} else {
58+
return nil
59+
}
60+
} catch {
61+
return .failure(error)
62+
}
63+
}
64+
65+
await submit(1)
66+
67+
var sum = 0
68+
while let r = await pull() {
69+
print("next: \(r)")
70+
await submit(1)
71+
72+
if sum >= 2 {
73+
print("task group returning: \(sum)")
74+
return sum
75+
}
76+
77+
sum += 1
78+
group.cancelAll() // cancel all after we receive one element
79+
}
80+
81+
print("bad, task group returning: \(sum)")
82+
return 0
83+
}
84+
}
85+
86+
// CHECK: main task
87+
// CHECK: next: 1
88+
// CHECK: next: 2
89+
// CHECK: task group returning: 3
90+
91+
launch { () async in
92+
let sum = await try! taskHandle.get()
93+
// CHECK: result: 2
94+
print("result: \(sum)")
95+
exit(0)
96+
}
97+
98+
print("main task")
99+
}
100+
101+
test_taskGroup_cancel_internally_afterOne()
102+
103+
dispatchMain()

test/Concurrency/async_task_groups.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ func test_taskGroup_add() async throws -> Int {
3333

3434
func test_taskGroup_addHandles() async throws -> Int {
3535
await try Task.withGroup(resultType: Int.self) { group in
36-
let one = await group.addWithHandle {
36+
let one = await group.add {
3737
await asyncFunc()
3838
}
3939

40-
let two = await group.addWithHandle {
40+
let two = await group.add {
4141
await asyncFunc()
4242
}
4343

@@ -48,11 +48,11 @@ func test_taskGroup_addHandles() async throws -> Int {
4848

4949
func test_taskGroup_cancel_handles() async throws {
5050
await try Task.withGroup(resultType: Int.self) { group in
51-
let one = await group.addWithHandle {
51+
let one = await group.add {
5252
await try asyncThrowsOnCancel()
5353
}
5454

55-
let two = await group.addWithHandle {
55+
let two = await group.add {
5656
await asyncFunc()
5757
}
5858

0 commit comments

Comments
 (0)