File tree Expand file tree Collapse file tree 2 files changed +54
-1
lines changed
stdlib/public/Concurrency Expand file tree Collapse file tree 2 files changed +54
-1
lines changed Original file line number Diff line number Diff line change @@ -772,7 +772,11 @@ void AsyncTask::dropInitialTaskExecutorPreferenceRecord() {
772
772
//
773
773
// This should not be done for withTaskExecutorPreference executors,
774
774
// however in that case, we would not enter this function here to clean up.
775
- swift_release (executorIdentityToRelease);
775
+ //
776
+ // NOTE: This MUST NOT assume that the object is a swift object (and use
777
+ // swift_release), because a dispatch_queue_t conforms to TaskExecutor,
778
+ // and may be passed in here; in which case swift_releasing it would be incorrect.
779
+ swift_unknownObjectRelease (executorIdentityToRelease);
776
780
}
777
781
778
782
/* *************************************************************************/
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments