Skip to content

Commit 423a87e

Browse files
authored
[Concurrency] Add test covering both serial and task executor in same type (#75393)
1 parent 95b431e commit 423a87e

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// NOT: %target-run-simple-swift( -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library)
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %target-build-swift -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library %s -o %t/a.out
5+
// RUN: %target-codesign %t/a.out
6+
// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=legacy %target-run %import-libdispatch %t/a.out
7+
// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=swift6 %target-run %import-libdispatch %t/a.out
8+
9+
// TODO: Need to find out how to combine %env- and %target-run and %import-libdispatch reliably.
10+
// UNSUPPORTED: OS=linux-gnu
11+
12+
// REQUIRES: concurrency
13+
// REQUIRES: executable_test
14+
// REQUIRES: libdispatch
15+
//
16+
// REQUIRES: concurrency_runtime
17+
// UNSUPPORTED: back_deployment_runtime
18+
19+
import Dispatch
20+
import _Concurrency
21+
22+
import Dispatch
23+
24+
final class DispatchQueueBothExecutor: @unchecked Sendable, SerialExecutor, TaskExecutor {
25+
let queue: DispatchQueue
26+
27+
init(queue: DispatchQueue) {
28+
self.queue = queue
29+
}
30+
31+
func enqueue(_ job: UnownedJob) {
32+
queue.async {
33+
job.runSynchronously(
34+
isolatedTo: self.asUnownedSerialExecutor(),
35+
taskExecutor: self.asUnownedTaskExecutor())
36+
}
37+
}
38+
39+
func checkIsolated() {
40+
dispatchPrecondition(condition: .onQueue(self.queue))
41+
}
42+
43+
func asUnownedTaskExecutor() -> UnownedTaskExecutor {
44+
.init(ordinary: self)
45+
}
46+
}
47+
48+
actor Kappa {
49+
func test() {
50+
self.preconditionIsolated()
51+
}
52+
}
53+
54+
actor QueueActor {
55+
let executor: DispatchQueueBothExecutor
56+
57+
init(executor: DispatchQueueBothExecutor) {
58+
self.executor = executor
59+
}
60+
61+
func test() {
62+
self.preconditionIsolated()
63+
}
64+
65+
nonisolated var unownedExecutor: UnownedSerialExecutor {
66+
self.executor.asUnownedSerialExecutor()
67+
}
68+
}
69+
70+
@main struct Main {
71+
72+
static func main() async {
73+
let executor = DispatchQueueBothExecutor(queue: DispatchQueue(label: "label"))
74+
let kappa = Kappa()
75+
76+
await withTaskGroup(of: Void.self) { group in
77+
78+
group.addTask(executorPreference: executor) {
79+
print("Task enqueued")
80+
81+
await kappa.test()
82+
print("Actor called")
83+
}
84+
}
85+
86+
let qa = QueueActor(executor: executor)
87+
await qa.test()
88+
print("Actor on queue executor called")
89+
90+
print("DONE")
91+
}
92+
}

0 commit comments

Comments
 (0)