Skip to content

Commit 8861585

Browse files
committed
[Concurrency] Add test for objc type TaskExecutor
1 parent b788dd1 commit 8861585

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking %import-libdispatch -parse-as-library )
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: concurrency
5+
// REQUIRES: libdispatch
6+
7+
// REQUIRES: OS=macosx
8+
// REQUIRES: objc_interop
9+
10+
// REQUIRES: concurrency_runtime
11+
// UNSUPPORTED: back_deployment_runtime
12+
13+
import Dispatch
14+
import StdlibUnittest
15+
import _Concurrency
16+
17+
import Foundation
18+
import Darwin
19+
20+
// Sneaky trick to make this type objc reference counted.
21+
//
22+
// This test specifically checks that our reference counting accounts for existence of
23+
// objective-c types as TaskExecutors -- which was a bug where we'd swift_release
24+
// obj-c excecutors by accident (rdar://131151645).
25+
final class NSQueueTaskExecutor: NSData, TaskExecutor, @unchecked Sendable {
26+
public func enqueue(_ _job: consuming ExecutorJob) {
27+
let job = UnownedJob(_job)
28+
DispatchQueue.main.async {
29+
job.runSynchronously(on: self.asUnownedTaskExecutor())
30+
}
31+
}
32+
}
33+
34+
@main struct Main {
35+
static func main() async {
36+
var taskExecutor: (any TaskExecutor)? = NSQueueTaskExecutor()
37+
38+
let task = Task(executorPreference: taskExecutor) {
39+
dispatchPrecondition(condition: .onQueue(DispatchQueue.main))
40+
try? await Task.sleep(for: .seconds(2))
41+
return 12
42+
}
43+
44+
taskExecutor = nil
45+
46+
let num = await task.value
47+
assert(num == 12)
48+
}
49+
}

0 commit comments

Comments
 (0)