Skip to content

Commit c7fedd4

Browse files
committed
[Executors] Fix delegation chain of Excecutor.enqueue for Job specifically
1 parent 0a55811 commit c7fedd4

File tree

2 files changed

+61
-16
lines changed

2 files changed

+61
-16
lines changed

stdlib/public/Concurrency/Executor.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,16 @@ public protocol SerialExecutor: Executor {
102102
#if !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
103103
@available(SwiftStdlib 5.9, *)
104104
extension Executor {
105+
106+
// Delegation goes like this:
107+
// Unowned Job -> Executor Job -> Job -> ---||---
108+
105109
public func enqueue(_ job: UnownedJob) {
106110
self.enqueue(ExecutorJob(job))
107111
}
108112

109113
public func enqueue(_ job: __owned ExecutorJob) {
110-
self.enqueue(UnownedJob(job))
114+
self.enqueue(Job(job))
111115
}
112116

113117
public func enqueue(_ job: __owned Job) {

test/Concurrency/Runtime/custom_executors_moveOnly_job.swift

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +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 {
1313
public func enqueue(_ job: UnownedJob) {
1414
job.runSynchronously(on: self.asUnownedSerialExecutor())
1515
}
16+
17+
var description: Swift.String {
18+
"\(Self.self)()"
19+
}
20+
}
21+
final class InlineExecutor_Job: SerialExecutor, CustomStringConvertible {
1622
public func enqueue(_ job: __owned Job) {
1723
job.runSynchronously(on: self.asUnownedSerialExecutor())
1824
}
25+
26+
var description: Swift.String {
27+
"\(Self.self)()"
28+
}
29+
}
30+
31+
final class InlineExecutor_ExecutorJob: SerialExecutor, CustomStringConvertible {
1932
public func enqueue(_ job: __owned ExecutorJob) {
2033
job.runSynchronously(on: self.asUnownedSerialExecutor())
2134
}
2235

2336
var description: Swift.String {
24-
"InlineExecutor()"
37+
"\(Self.self)()"
2538
}
2639
}
2740

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

3045
actor Custom {
3146
var count = 0
3247

48+
let selectedExecutor: any SerialExecutor
49+
3350
nonisolated var unownedExecutor: UnownedSerialExecutor {
34-
print("custom unownedExecutor")
35-
return inlineExecutor.asUnownedSerialExecutor()
51+
print("unownedExecutor: \(self.selectedExecutor)")
52+
return selectedExecutor.asUnownedSerialExecutor()
53+
}
54+
55+
init(selectedExecutor: some SerialExecutor) {
56+
self.selectedExecutor = selectedExecutor
3657
}
3758

3859
func report() async {
@@ -44,20 +65,40 @@ actor Custom {
4465
@available(SwiftStdlib 5.1, *)
4566
@main struct Main {
4667
static func main() async {
47-
print("begin")
48-
let actor = Custom()
49-
await actor.report()
50-
await actor.report()
51-
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+
5283
print("end")
5384
}
5485
}
5586

56-
// CHECK: begin
57-
// 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
58101
// CHECK-NEXT: custom.count == 0
59-
// CHECK-NEXT: custom unownedExecutor
102+
// CHECK-NEXT: unownedExecutor: InlineExecutor_ExecutorJob
60103
// CHECK-NEXT: custom.count == 1
61-
// CHECK-NEXT: custom unownedExecutor
62-
// CHECK-NEXT: custom.count == 2
63104
// CHECK-NEXT: end

0 commit comments

Comments
 (0)