Skip to content

Commit d1973d6

Browse files
authored
Merge pull request #65734 from ktoso/pick-wip-delegation-chain-fix-executors
2 parents 6156351 + b8d2680 commit d1973d6

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-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: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,52 @@
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+
22+
final class InlineExecutor_Job: SerialExecutor, CustomStringConvertible {
1623
public func enqueue(_ job: __owned Job) {
1724
job.runSynchronously(on: self.asUnownedSerialExecutor())
1825
}
26+
27+
var description: Swift.String {
28+
"\(Self.self)()"
29+
}
30+
}
31+
32+
final class InlineExecutor_ExecutorJob: SerialExecutor, CustomStringConvertible {
1933
public func enqueue(_ job: __owned ExecutorJob) {
2034
job.runSynchronously(on: self.asUnownedSerialExecutor())
2135
}
2236

2337
var description: Swift.String {
24-
"InlineExecutor()"
38+
"\(Self.self)()"
2539
}
2640
}
2741

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

3046
actor Custom {
3147
var count = 0
3248

49+
let selectedExecutor: any SerialExecutor
50+
3351
nonisolated var unownedExecutor: UnownedSerialExecutor {
34-
print("custom unownedExecutor")
35-
return inlineExecutor.asUnownedSerialExecutor()
52+
print("unownedExecutor: \(self.selectedExecutor)")
53+
return selectedExecutor.asUnownedSerialExecutor()
54+
}
55+
56+
init(selectedExecutor: some SerialExecutor) {
57+
self.selectedExecutor = selectedExecutor
3658
}
3759

3860
func report() async {
@@ -44,20 +66,40 @@ actor Custom {
4466
@available(SwiftStdlib 5.1, *)
4567
@main struct Main {
4668
static func main() async {
47-
print("begin")
48-
let actor = Custom()
49-
await actor.report()
50-
await actor.report()
51-
await actor.report()
69+
print("begin - unowned")
70+
let one = Custom(selectedExecutor: inlineExecutor_UnownedJob)
71+
await one.report()
72+
await one.report()
73+
74+
print("begin - job")
75+
let two = Custom(selectedExecutor: inlineExecutor_Job)
76+
await two.report()
77+
await two.report()
78+
79+
print("begin - executor job")
80+
let three = Custom(selectedExecutor: inlineExecutor_ExecutorJob)
81+
await three.report()
82+
await three.report()
83+
5284
print("end")
5385
}
5486
}
5587

56-
// CHECK: begin
57-
// CHECK-NEXT: custom unownedExecutor
88+
// CHECK: begin - unowned
89+
// CHECK-NEXT: unownedExecutor: InlineExecutor_UnownedJob
90+
// CHECK-NEXT: custom.count == 0
91+
// CHECK-NEXT: unownedExecutor: InlineExecutor_UnownedJob
92+
// CHECK-NEXT: custom.count == 1
93+
94+
// CHECK: begin - job
95+
// CHECK-NEXT: unownedExecutor: InlineExecutor_Job
96+
// CHECK-NEXT: custom.count == 0
97+
// CHECK-NEXT: unownedExecutor: InlineExecutor_Job
98+
// CHECK-NEXT: custom.count == 1
99+
100+
// CHECK: begin - executor job
101+
// CHECK-NEXT: unownedExecutor: InlineExecutor_ExecutorJob
58102
// CHECK-NEXT: custom.count == 0
59-
// CHECK-NEXT: custom unownedExecutor
103+
// CHECK-NEXT: unownedExecutor: InlineExecutor_ExecutorJob
60104
// CHECK-NEXT: custom.count == 1
61-
// CHECK-NEXT: custom unownedExecutor
62-
// CHECK-NEXT: custom.count == 2
63105
// CHECK-NEXT: end

0 commit comments

Comments
 (0)