@@ -16,14 +16,18 @@ import Swift
16
16
@available ( SwiftStdlib 5 . 1 , * )
17
17
public protocol Executor : AnyObject , Sendable {
18
18
19
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
19
20
@available ( macOS, introduced: 10.15 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
20
21
@available ( iOS, introduced: 13.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
21
22
@available ( watchOS, introduced: 6.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
22
23
@available ( tvOS, introduced: 13.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
24
+ #endif
23
25
func enqueue( _ job: UnownedJob )
24
26
27
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
25
28
@available ( SwiftStdlib 5 . 9 , * )
26
29
func enqueue( _ job: __owned Job)
30
+ #endif // !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
27
31
}
28
32
29
33
/// A service that executes jobs.
@@ -34,35 +38,45 @@ public protocol SerialExecutor: Executor {
34
38
// avoid drilling down to the base conformance just for the basic
35
39
// work-scheduling operation.
36
40
@_nonoverride
41
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
37
42
@available ( macOS, introduced: 10.15 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
38
43
@available ( iOS, introduced: 13.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
39
44
@available ( watchOS, introduced: 6.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
40
45
@available ( tvOS, introduced: 13.0 , deprecated: 9999 , message: " Implement 'enqueue(_: __owned Job)' instead " )
46
+ #endif
41
47
func enqueue( _ job: UnownedJob )
42
48
49
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
43
50
// This requirement is repeated here as a non-override so that we
44
51
// get a redundant witness-table entry for it. This allows us to
45
52
// avoid drilling down to the base conformance just for the basic
46
53
// work-scheduling operation.
47
54
@_nonoverride
48
55
@available ( SwiftStdlib 5 . 9 , * )
49
56
func enqueue( _ job: __owned Job)
57
+ #endif // !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
50
58
51
59
/// Convert this executor value to the optimized form of borrowed
52
60
/// executor references.
61
+ ///
62
+ /// By default executors are "ordinary", i.e. exhibit no special behavior,
63
+ /// implement this method if your executor implementation has some special semantics
64
+ /// that it needs to convey in its `UnownedSerialExecutor`.
53
65
@available ( SwiftStdlib 5 . 9 , * )
54
66
func asUnownedSerialExecutor( ) -> UnownedSerialExecutor
55
67
}
56
68
57
69
@available ( SwiftStdlib 5 . 9 , * )
58
70
extension Executor {
71
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
59
72
public func enqueue( _ job: UnownedJob ) {
60
73
self . enqueue ( Job ( job) )
61
74
}
62
75
63
76
public func enqueue( _ job: __owned Job) {
64
77
self . enqueue ( UnownedJob ( job) )
65
78
}
79
+ #endif
66
80
}
67
81
68
82
@available ( SwiftStdlib 5 . 9 , * )
@@ -84,37 +98,37 @@ extension SerialExecutor {
84
98
/// also keep the actor's associated executor alive; if they are
85
99
/// different objects, the executor must be referenced strongly by the
86
100
/// actor.
87
- @available ( SwiftStdlib 5 . 1 , * )
88
- @frozen
89
- public struct UnownedSerialExecutor : Sendable {
90
- #if compiler(>=5.5) && $BuiltinExecutor
91
- @usableFromInline
92
- internal var executor : Builtin . Executor
93
-
94
- @_spi ( ConcurrencyExecutors)
95
- @available ( SwiftStdlib 5 . 9 , * )
96
- public var _executor : Builtin . Executor {
97
- self . executor
98
- }
99
- #endif
100
-
101
- @inlinable
102
- internal init ( _ executor: Builtin . Executor ) {
101
+ @available ( SwiftStdlib 5 . 1 , * )
102
+ @frozen
103
+ public struct UnownedSerialExecutor : Sendable {
103
104
#if compiler(>=5.5) && $BuiltinExecutor
104
- self . executor = executor
105
+ @usableFromInline
106
+ internal var executor : Builtin . Executor
107
+
108
+ @_spi ( ConcurrencyExecutors)
109
+ @available ( SwiftStdlib 5 . 9 , * )
110
+ public var _executor : Builtin . Executor {
111
+ self . executor
112
+ }
105
113
#endif
106
- }
107
114
108
- @inlinable
109
- public init < E: SerialExecutor > ( ordinary executor: __shared E) {
110
- #if compiler(>=5.5) && $BuiltinBuildExecutor
111
- self . executor = Builtin . buildOrdinarySerialExecutorRef ( executor)
112
- #else
113
- fatalError ( " Swift compiler is incompatible with this SDK version " )
114
- #endif
115
- }
115
+ @inlinable
116
+ internal init ( _ executor: Builtin . Executor ) {
117
+ #if compiler(>=5.5) && $BuiltinExecutor
118
+ self . executor = executor
119
+ #endif
120
+ }
121
+
122
+ @inlinable
123
+ public init < E: SerialExecutor > ( ordinary executor: __shared E) {
124
+ #if compiler(>=5.5) && $BuiltinBuildExecutor
125
+ self . executor = Builtin . buildOrdinarySerialExecutorRef ( executor)
126
+ #else
127
+ fatalError ( " Swift compiler is incompatible with this SDK version " )
128
+ #endif
129
+ }
116
130
117
- }
131
+ }
118
132
119
133
/// Checks if the current task is running on the expected executor.
120
134
///
@@ -124,57 +138,60 @@ public struct UnownedSerialExecutor: Sendable {
124
138
/// additional runtime check for this, especially when moving towards Swift
125
139
/// concurrency from other runtimes which frequently use such assertions.
126
140
/// - Parameter executor: The expected executor.
127
- @available ( SwiftStdlib 5 . 9 , * )
128
- @_silgen_name ( " swift_task_isOnExecutor " )
129
- public func _taskIsOnExecutor< Executor: SerialExecutor > ( _ executor: Executor ) -> Bool
130
-
131
- @available ( SwiftStdlib 5 . 1 , * )
132
- @_transparent
133
- public // COMPILER_INTRINSIC
134
- func _checkExpectedExecutor( _filenameStart: Builtin . RawPointer ,
135
- _filenameLength: Builtin . Word ,
136
- _filenameIsASCII: Builtin . Int1 ,
137
- _line: Builtin . Word ,
138
- _executor: Builtin . Executor ) {
139
- if _taskIsCurrentExecutor ( _executor) {
140
- return
141
+ @available ( SwiftStdlib 5 . 9 , * )
142
+ @_silgen_name ( " swift_task_isOnExecutor " )
143
+ public func _taskIsOnExecutor< Executor: SerialExecutor > ( _ executor: Executor ) -> Bool
144
+
145
+ @available ( SwiftStdlib 5 . 1 , * )
146
+ @_transparent
147
+ public // COMPILER_INTRINSIC
148
+ func _checkExpectedExecutor( _filenameStart: Builtin . RawPointer ,
149
+ _filenameLength: Builtin . Word ,
150
+ _filenameIsASCII: Builtin . Int1 ,
151
+ _line: Builtin . Word ,
152
+ _executor: Builtin . Executor ) {
153
+ if _taskIsCurrentExecutor ( _executor) {
154
+ return
155
+ }
156
+
157
+ _reportUnexpectedExecutor (
158
+ _filenameStart, _filenameLength, _filenameIsASCII, _line, _executor)
141
159
}
142
160
143
- _reportUnexpectedExecutor (
144
- _filenameStart, _filenameLength, _filenameIsASCII, _line, _executor)
145
- }
146
-
147
161
/// Primarily a debug utility.
148
162
///
149
163
/// If the passed in Job is a Task, returns the complete 64bit TaskId,
150
164
/// otherwise returns only the job's 32bit Id.
151
165
///
152
166
/// - Returns: the Id stored in this Job or Task, for purposes of debug printing
153
- @available ( SwiftStdlib 5 . 9 , * )
154
- @_silgen_name ( " swift_task_getJobTaskId " )
155
- internal func _getJobTaskId( _ job: UnownedJob ) -> UInt64
167
+ @available ( SwiftStdlib 5 . 9 , * )
168
+ @_silgen_name ( " swift_task_getJobTaskId " )
169
+ internal func _getJobTaskId( _ job: UnownedJob ) -> UInt64
156
170
157
171
// Used by the concurrency runtime
158
- @available ( SwiftStdlib 5 . 1 , * )
159
- @_silgen_name ( " _swift_task_enqueueOnExecutor " )
160
- internal func _enqueueOnExecutor< E > ( job unownedJob: UnownedJob, executor: E)
161
- where E: SerialExecutor {
162
- if #available( SwiftStdlib 5 . 9 , * ) {
163
- executor. enqueue ( Job ( context: unownedJob. _context) )
164
- } else {
172
+ @available ( SwiftStdlib 5 . 1 , * )
173
+ @_silgen_name ( " _swift_task_enqueueOnExecutor " )
174
+ internal func _enqueueOnExecutor< E > ( job unownedJob: UnownedJob, executor: E)
175
+ where E: SerialExecutor {
176
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
177
+ if #available( SwiftStdlib 5 . 9 , * ) {
178
+ executor. enqueue ( Job ( context: unownedJob. _context) )
179
+ } else {
180
+ }
181
+ #else
165
182
executor. enqueue ( unownedJob)
183
+ #endif
166
184
}
167
- }
168
185
169
- #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
186
+ #if !SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
170
187
// This must take a DispatchQueueShim, not something like AnyObject,
171
188
// or else SILGen will emit a retain/release in unoptimized builds,
172
189
// which won't work because DispatchQueues aren't actually
173
190
// Swift-retainable.
174
- @available ( SwiftStdlib 5 . 1 , * )
175
- @_silgen_name ( " swift_task_enqueueOnDispatchQueue " )
176
- internal func _enqueueOnDispatchQueue( _ job: UnownedJob ,
177
- queue: DispatchQueueShim )
191
+ @available ( SwiftStdlib 5 . 1 , * )
192
+ @_silgen_name ( " swift_task_enqueueOnDispatchQueue " )
193
+ internal func _enqueueOnDispatchQueue( _ job: UnownedJob ,
194
+ queue: DispatchQueueShim )
178
195
179
196
/// Used by the runtime solely for the witness table it produces.
180
197
/// FIXME: figure out some way to achieve that which doesn't generate
@@ -183,14 +200,14 @@ internal func _enqueueOnDispatchQueue(_ job: UnownedJob,
183
200
/// Expected to work for any primitive dispatch queue; note that this
184
201
/// means a dispatch_queue_t, which is not the same as DispatchQueue
185
202
/// on platforms where that is an instance of a wrapper class.
186
- @available( SwiftStdlib 5 . 1 , * )
187
- internal final class DispatchQueueShim: @unchecked Sendable , SerialExecutor {
188
- func enqueue( _ job: UnownedJob ) {
189
- _enqueueOnDispatchQueue ( job, queue: self )
190
- }
191
-
192
- func asUnownedSerialExecutor( ) -> UnownedSerialExecutor {
193
- return UnownedSerialExecutor ( ordinary: self )
203
+ @available( SwiftStdlib 5 . 1 , * )
204
+ internal final class DispatchQueueShim: @unchecked Sendable , SerialExecutor {
205
+ func enqueue( _ job: UnownedJob ) {
206
+ _enqueueOnDispatchQueue ( job, queue: self )
207
+ }
208
+
209
+ func asUnownedSerialExecutor( ) -> UnownedSerialExecutor {
210
+ return UnownedSerialExecutor ( ordinary: self )
211
+ }
194
212
}
195
- }
196
- #endif // SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
213
+ #endif // SWIFT_STDLIB_SINGLE_THREADED_CONCURRENCY
0 commit comments