Skip to content

Commit 2ba2332

Browse files
committed
[Executors] Fix delegation chain of Excecutor.enqueue for Job specifically
1 parent 2d89b20 commit 2ba2332

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

stdlib/public/Concurrency/Executor.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ public protocol SerialExecutor: Executor {
8585
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
8686
@available(SwiftStdlib 5.9, *)
8787
extension Executor {
88+
89+
// Delegation goes like this:
90+
// Unowned Job -> Executor Job -> Job -> ---||---
91+
8892
public func enqueue(_ job: UnownedJob) {
8993
self.enqueue(ExecutorJob(job))
9094
}
9195

9296
public func enqueue(_ job: __owned ExecutorJob) {
93-
self.enqueue(UnownedJob(job))
97+
self.enqueue(Job(job))
9498
}
9599
}
96100
#endif // !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY

test/Concurrency/Runtime/custom_executors_moveOnly_job.swift

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,51 @@
99
// UNSUPPORTED: back_deployment_runtime
1010
// REQUIRES: concurrency_runtime
1111

12-
final class InlineExecutor: SerialExecutor, CustomStringConvertible {
12+
final class InlineExecutor_UnownedJob: SerialExecutor, CustomStringConvertible {
13+
public func enqueue(_ job: UnownedJob) {
14+
job.runSynchronously(on: self.asUnownedSerialExecutor())
15+
}
16+
17+
var description: Swift.String {
18+
"\(Self.self)()"
19+
}
20+
}
21+
final class InlineExecutor_Job: SerialExecutor, CustomStringConvertible {
22+
public func enqueue(_ job: __owned Job) {
23+
job.runSynchronously(on: self.asUnownedSerialExecutor())
24+
}
25+
26+
var description: Swift.String {
27+
"\(Self.self)()"
28+
}
29+
}
30+
31+
final class InlineExecutor_ExecutorJob: SerialExecutor, CustomStringConvertible {
1332
public func enqueue(_ job: __owned ExecutorJob) {
1433
job.runSynchronously(on: self.asUnownedSerialExecutor())
1534
}
1635

1736
var description: Swift.String {
18-
"InlineExecutor()"
37+
"\(Self.self)()"
1938
}
2039
}
2140

22-
let inlineExecutor = InlineExecutor()
41+
let inlineExecutor_UnownedJob = InlineExecutor_UnownedJob()
42+
let inlineExecutor_Job = InlineExecutor_Job()
43+
let inlineExecutor_ExecutorJob = InlineExecutor_ExecutorJob()
2344

2445
actor Custom {
2546
var count = 0
2647

48+
let selectedExecutor: any SerialExecutor
49+
2750
nonisolated var unownedExecutor: UnownedSerialExecutor {
28-
print("custom unownedExecutor")
29-
return inlineExecutor.asUnownedSerialExecutor()
51+
print("unownedExecutor: \(self.selectedExecutor)")
52+
return selectedExecutor.asUnownedSerialExecutor()
53+
}
54+
55+
init(selectedExecutor: some SerialExecutor) {
56+
self.selectedExecutor = selectedExecutor
3057
}
3158

3259
func report() async {
@@ -38,20 +65,40 @@ actor Custom {
3865
@available(SwiftStdlib 5.1, *)
3966
@main struct Main {
4067
static func main() async {
41-
print("begin")
42-
let actor = Custom()
43-
await actor.report()
44-
await actor.report()
45-
await actor.report()
68+
print("begin - unowned")
69+
let one = Custom(selectedExecutor: inlineExecutor_UnownedJob)
70+
await one.report()
71+
await one.report()
72+
73+
print("begin - job")
74+
let two = Custom(selectedExecutor: inlineExecutor_Job)
75+
await two.report()
76+
await two.report()
77+
78+
print("begin - executor job")
79+
let three = Custom(selectedExecutor: inlineExecutor_ExecutorJob)
80+
await three.report()
81+
await three.report()
82+
4683
print("end")
4784
}
4885
}
4986

50-
// CHECK: begin
51-
// CHECK-NEXT: custom unownedExecutor
87+
// CHECK: begin - unowned
88+
// CHECK-NEXT: unownedExecutor: InlineExecutor_UnownedJob
89+
// CHECK-NEXT: custom.count == 0
90+
// CHECK-NEXT: unownedExecutor: InlineExecutor_UnownedJob
91+
// CHECK-NEXT: custom.count == 1
92+
93+
// CHECK: begin - job
94+
// CHECK-NEXT: unownedExecutor: InlineExecutor_Job
95+
// CHECK-NEXT: custom.count == 0
96+
// CHECK-NEXT: unownedExecutor: InlineExecutor_Job
97+
// CHECK-NEXT: custom.count == 1
98+
99+
// CHECK: begin - executor job
100+
// CHECK-NEXT: unownedExecutor: InlineExecutor_ExecutorJob
52101
// CHECK-NEXT: custom.count == 0
53-
// CHECK-NEXT: custom unownedExecutor
102+
// CHECK-NEXT: unownedExecutor: InlineExecutor_ExecutorJob
54103
// CHECK-NEXT: custom.count == 1
55-
// CHECK-NEXT: custom unownedExecutor
56-
// CHECK-NEXT: custom.count == 2
57104
// CHECK-NEXT: end

0 commit comments

Comments
 (0)