Skip to content

Commit f0cd742

Browse files
committed
[Concurrency] Mark all of the custom global excecutor API as SPI for now.
Also expose CooperativeExecutor as public (but SPI). rdar://151147606
1 parent e473977 commit f0cd742

25 files changed

+212
-2
lines changed

stdlib/public/Concurrency/CFExecutor.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum CoreFoundation {
4343

4444
// .. Main Executor ............................................................
4545

46+
@_spi(CustomDefaultExecutors)
4647
@available(StdlibDeploymentTarget 6.2, *)
4748
public final class CFMainExecutor: DispatchMainExecutor, @unchecked Sendable {
4849

@@ -58,6 +59,7 @@ public final class CFMainExecutor: DispatchMainExecutor, @unchecked Sendable {
5859

5960
// .. Task Executor ............................................................
6061

62+
@_spi(CustomDefaultExecutors)
6163
@available(StdlibDeploymentTarget 6.2, *)
6264
public final class CFTaskExecutor: DispatchGlobalTaskExecutor,
6365
@unchecked Sendable {

stdlib/public/Concurrency/Clock.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public protocol Clock<Duration>: Sendable {
4343
#endif
4444

4545
/// The traits associated with this clock instance.
46+
@_spi(CustomDefaultExecutors)
4647
@available(StdlibDeploymentTarget 6.2, *)
4748
var traits: ClockTraits { get }
4849

@@ -59,6 +60,7 @@ public protocol Clock<Duration>: Sendable {
5960
///
6061
/// Returns: A `Swift.Duration` representing the equivalent duration, or
6162
/// `nil` if this function is not supported.
63+
@_spi(CustomDefaultExecutors)
6264
@available(StdlibDeploymentTarget 6.2, *)
6365
func convert(from duration: Duration) -> Swift.Duration?
6466

@@ -70,6 +72,7 @@ public protocol Clock<Duration>: Sendable {
7072
///
7173
/// Returns: A `Duration` representing the equivalent duration, or
7274
/// `nil` if this function is not supported.
75+
@_spi(CustomDefaultExecutors)
7376
@available(StdlibDeploymentTarget 6.2, *)
7477
func convert(from duration: Swift.Duration) -> Duration?
7578

@@ -82,6 +85,7 @@ public protocol Clock<Duration>: Sendable {
8285
///
8386
/// Returns: An `Instant` representing the equivalent instant, or
8487
/// `nil` if this function is not supported.
88+
@_spi(CustomDefaultExecutors)
8589
@available(StdlibDeploymentTarget 6.2, *)
8690
func convert<OtherClock: Clock>(instant: OtherClock.Instant,
8791
from clock: OtherClock) -> Instant?
@@ -140,6 +144,7 @@ extension Clock {
140144
}
141145
}
142146

147+
@_spi(CustomDefaultExecutors)
143148
@available(StdlibDeploymentTarget 6.2, *)
144149
extension Clock {
145150
// For compatibility, return `nil` if this is not implemented
@@ -171,6 +176,7 @@ extension Clock {
171176
}
172177
}
173178

179+
@_spi(CustomDefaultExecutors)
174180
@available(StdlibDeploymentTarget 6.2, *)
175181
extension Clock where Duration == Swift.Duration {
176182
public func convert(from duration: Duration) -> Duration? {
@@ -207,6 +213,7 @@ extension Clock {
207213
/// clocks best matches the clock that the user is trying to specify a
208214
/// time or delay in. Executors are expected to do this on a best effort
209215
/// basis.
216+
@_spi(CustomDefaultExecutors)
210217
@available(StdlibDeploymentTarget 6.2, *)
211218
public struct ClockTraits: OptionSet {
212219
public let rawValue: UInt32
@@ -225,6 +232,7 @@ public struct ClockTraits: OptionSet {
225232
public static let wallTime = ClockTraits(rawValue: 1 << 2)
226233
}
227234

235+
@_spi(CustomDefaultExecutors)
228236
@available(StdlibDeploymentTarget 6.2, *)
229237
extension Clock {
230238
/// The traits associated with this clock instance.

stdlib/public/Concurrency/ContinuousClock.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ extension ContinuousClock: Clock {
101101
}
102102

103103
/// The continuous clock is continuous and monotonic
104+
@_spi(CustomDefaultExecutors)
104105
@available(StdlibDeploymentTarget 6.2, *)
105106
public var traits: ClockTraits {
106107
return [.continuous, .monotonic]

stdlib/public/Concurrency/CooperativeExecutor.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ extension ExecutorJob {
9999

100100
/// A co-operative executor that can be used as the main executor or as a
101101
/// task executor.
102+
@_spi(CustomDefaultExecutors)
102103
@available(StdlibDeploymentTarget 6.2, *)
103-
class CooperativeExecutor: Executor, @unchecked Sendable {
104+
public class CooperativeExecutor: Executor, @unchecked Sendable {
104105
var runQueue: PriorityQueue<UnownedJob>
105106
var waitQueue: PriorityQueue<UnownedJob>
106107
var shouldStop: Bool = false
@@ -179,6 +180,7 @@ class CooperativeExecutor: Executor, @unchecked Sendable {
179180
public var asSchedulable: any SchedulableExecutor { self }
180181
}
181182

183+
@_spi(CustomDefaultExecutors)
182184
@available(StdlibDeploymentTarget 6.2, *)
183185
extension CooperativeExecutor: SchedulableExecutor {
184186
var currentTime: Timestamp {
@@ -202,6 +204,7 @@ extension CooperativeExecutor: SchedulableExecutor {
202204
}
203205
}
204206

207+
@_spi(CustomDefaultExecutors)
205208
@available(StdlibDeploymentTarget 6.2, *)
206209
extension CooperativeExecutor: RunLoopExecutor {
207210
public func run() throws {
@@ -249,12 +252,15 @@ extension CooperativeExecutor: RunLoopExecutor {
249252
}
250253
}
251254

255+
@_spi(CustomDefaultExecutors)
252256
@available(StdlibDeploymentTarget 6.2, *)
253257
extension CooperativeExecutor: SerialExecutor {}
254258

259+
@_spi(CustomDefaultExecutors)
255260
@available(StdlibDeploymentTarget 6.2, *)
256261
extension CooperativeExecutor: TaskExecutor {}
257262

263+
@_spi(CustomDefaultExecutors)
258264
@available(StdlibDeploymentTarget 6.2, *)
259265
extension CooperativeExecutor: MainExecutor {}
260266

stdlib/public/Concurrency/DispatchExecutor.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Swift
2323

2424
// .. Main Executor ............................................................
2525

26+
@_spi(CustomDefaultExecutors)
2627
@available(StdlibDeploymentTarget 6.2, *)
2728
public class DispatchMainExecutor: RunLoopExecutor, @unchecked Sendable {
2829
var threaded = false
@@ -43,6 +44,7 @@ public class DispatchMainExecutor: RunLoopExecutor, @unchecked Sendable {
4344
}
4445
}
4546

47+
@_spi(CustomDefaultExecutors)
4648
@available(StdlibDeploymentTarget 6.2, *)
4749
extension DispatchMainExecutor: SerialExecutor {
4850

@@ -57,6 +59,7 @@ extension DispatchMainExecutor: SerialExecutor {
5759
}
5860
}
5961

62+
@_spi(CustomDefaultExecutors)
6063
@available(StdlibDeploymentTarget 6.2, *)
6164
extension DispatchMainExecutor: SchedulableExecutor {
6265
public var asSchedulable: SchedulableExecutor? {
@@ -85,11 +88,13 @@ extension DispatchMainExecutor: SchedulableExecutor {
8588
}
8689
}
8790

91+
@_spi(CustomDefaultExecutors)
8892
@available(StdlibDeploymentTarget 6.2, *)
8993
extension DispatchMainExecutor: MainExecutor {}
9094

9195
// .. Task Executor ............................................................
9296

97+
@_spi(CustomDefaultExecutors)
9398
@available(StdlibDeploymentTarget 6.2, *)
9499
public class DispatchGlobalTaskExecutor: TaskExecutor, SchedulableExecutor,
95100
@unchecked Sendable {
@@ -201,10 +206,12 @@ extension DispatchExecutorProtocol {
201206

202207
}
203208

209+
@_spi(CustomDefaultExecutors)
204210
@available(StdlibDeploymentTarget 6.2, *)
205211
extension DispatchGlobalTaskExecutor: DispatchExecutorProtocol {
206212
}
207213

214+
@_spi(CustomDefaultExecutors)
208215
@available(StdlibDeploymentTarget 6.2, *)
209216
extension DispatchMainExecutor: DispatchExecutorProtocol {
210217
}

stdlib/public/Concurrency/DummyExecutor.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Swift
1414

1515
// .. Main Executor ............................................................
1616

17+
@_spi(CustomDefaultExecutors)
1718
@available(SwiftStdlib 6.2, *)
1819
public final class DummyMainExecutor: MainExecutor, @unchecked Sendable {
1920
public init() {}
@@ -45,6 +46,7 @@ public final class DummyMainExecutor: MainExecutor, @unchecked Sendable {
4546

4647
// .. Task Executor ............................................................
4748

49+
@_spi(CustomDefaultExecutors)
4850
@available(SwiftStdlib 6.2, *)
4951
public final class DummyTaskExecutor: TaskExecutor, @unchecked Sendable {
5052
public init() {}

stdlib/public/Concurrency/Executor.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ public protocol Executor: AnyObject, Sendable {
3838

3939
#if !$Embedded
4040
/// `true` if this is the main executor.
41+
@_spi(CustomDefaultExecutors)
4142
@available(StdlibDeploymentTarget 6.2, *)
4243
var isMainExecutor: Bool { get }
4344
#endif
4445
}
4546

47+
@_spi(CustomDefaultExecutors)
4648
@available(StdlibDeploymentTarget 6.2, *)
4749
public protocol SchedulableExecutor: Executor {
4850

@@ -63,6 +65,7 @@ public protocol SchedulableExecutor: Executor {
6365
/// - tolerance: The maximum additional delay permissible before the
6466
/// job is executed. `nil` means no limit.
6567
/// - clock: The clock used for the delay.
68+
@_spi(CustomDefaultExecutors)
6669
@available(StdlibDeploymentTarget 6.2, *)
6770
func enqueue<C: Clock>(_ job: consuming ExecutorJob,
6871
after delay: C.Duration,
@@ -83,6 +86,7 @@ public protocol SchedulableExecutor: Executor {
8386
/// - tolerance: The maximum additional delay permissible before the
8487
/// job is executed. `nil` means no limit.
8588
/// - clock: The clock used for the delay..
89+
@_spi(CustomDefaultExecutors)
8690
@available(StdlibDeploymentTarget 6.2, *)
8791
func enqueue<C: Clock>(_ job: consuming ExecutorJob,
8892
at instant: C.Instant,
@@ -160,6 +164,7 @@ extension SchedulableExecutor {
160164

161165
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
162166

167+
@_spi(CustomDefaultExecutors)
163168
@available(StdlibDeploymentTarget 6.2, *)
164169
public func enqueue<C: Clock>(_ job: consuming ExecutorJob,
165170
after delay: C.Duration,
@@ -171,6 +176,7 @@ extension SchedulableExecutor {
171176
tolerance: tolerance, clock: clock)
172177
}
173178

179+
@_spi(CustomDefaultExecutors)
174180
@available(StdlibDeploymentTarget 6.2, *)
175181
public func enqueue<C: Clock>(_ job: consuming ExecutorJob,
176182
at instant: C.Instant,
@@ -360,6 +366,7 @@ public protocol SerialExecutor: Executor {
360366
/// The default implementation returns `nil` is used to indicate that it is "unknown" if the current context is
361367
/// isolated by this serial executor. The runtime then _may_ proceed to invoke `checkIsolated()` as a last-resort
362368
/// attempt to verify the isolation of the current context.
369+
@_spi(CustomDefaultExecutors)
363370
@available(StdlibDeploymentTarget 6.2, *)
364371
func isIsolatingCurrentContext() -> Bool?
365372

@@ -369,6 +376,7 @@ public protocol SerialExecutor: Executor {
369376
extension SerialExecutor {
370377

371378
#if !$Embedded && !SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
379+
@_spi(CustomDefaultExecutors)
372380
@available(StdlibDeploymentTarget 6.2, *)
373381
public var isMainExecutor: Bool { return MainActor.executor._isSameExecutor(self) }
374382
#endif
@@ -512,9 +520,11 @@ extension SerialExecutor {
512520

513521
}
514522

523+
@_spi(CustomDefaultExecutors)
515524
@available(StdlibDeploymentTarget 6.2, *)
516525
extension SerialExecutor where Self: Equatable {
517526

527+
@_spi(CustomDefaultExecutors)
518528
@available(StdlibDeploymentTarget 6.2, *)
519529
public func isSameExclusiveExecutionContext(other: Self) -> Bool {
520530
return self == other
@@ -527,6 +537,7 @@ extension SerialExecutor where Self: Equatable {
527537
/// The idea here is that some executors may work by running a loop
528538
/// that processes events of some sort; we want a way to enter that loop,
529539
/// and we would also like a way to trigger the loop to exit.
540+
@_spi(CustomDefaultExecutors)
530541
@available(StdlibDeploymentTarget 6.2, *)
531542
public protocol RunLoopExecutor: Executor {
532543
/// Run the executor's run loop.
@@ -558,6 +569,7 @@ public protocol RunLoopExecutor: Executor {
558569
func stop()
559570
}
560571

572+
@_spi(CustomDefaultExecutors)
561573
@available(StdlibDeploymentTarget 6.2, *)
562574
extension RunLoopExecutor {
563575

@@ -570,13 +582,15 @@ extension RunLoopExecutor {
570582

571583
/// The main executor must conform to these three protocols; we have to
572584
/// make this a protocol for compatibility with Embedded Swift.
585+
@_spi(CustomDefaultExecutors)
573586
@available(StdlibDeploymentTarget 6.2, *)
574587
public protocol MainExecutor: RunLoopExecutor, SerialExecutor {
575588
}
576589

577590

578591
/// An ExecutorFactory is used to create the default main and task
579592
/// executors.
593+
@_spi(CustomDefaultExecutors)
580594
@available(StdlibDeploymentTarget 6.2, *)
581595
public protocol ExecutorFactory {
582596
#if !$Embedded
@@ -590,9 +604,11 @@ public protocol ExecutorFactory {
590604
static var defaultExecutor: any TaskExecutor { get }
591605
}
592606

607+
@_spi(CustomDefaultExecutors)
593608
@available(StdlibDeploymentTarget 6.2, *)
594-
typealias DefaultExecutorFactory = PlatformExecutorFactory
609+
public typealias DefaultExecutorFactory = PlatformExecutorFactory
595610

611+
@_spi(CustomDefaultExecutors)
596612
@available(StdlibDeploymentTarget 6.2, *)
597613
@_silgen_name("swift_createExecutors")
598614
public func _createExecutors<F: ExecutorFactory>(factory: F.Type) {
@@ -620,6 +636,7 @@ extension MainActor {
620636
///
621637
/// Attempting to set this after the first `enqueue` on the main
622638
/// executor is a fatal error.
639+
@_spi(CustomDefaultExecutors)
623640
@available(StdlibDeploymentTarget 6.2, *)
624641
public static var executor: any MainExecutor {
625642
// It would be good if there was a Swift way to do this
@@ -638,6 +655,7 @@ extension Task where Success == Never, Failure == Never {
638655
///
639656
/// Attempting to set this after the first `enqueue` on the global
640657
/// executor is a fatal error.
658+
@_spi(CustomDefaultExecutors)
641659
@available(StdlibDeploymentTarget 6.2, *)
642660
public static var defaultExecutor: any TaskExecutor {
643661
// It would be good if there was a Swift way to do this
@@ -658,6 +676,7 @@ extension Task where Success == Never, Failure == Never {
658676
/// 3. The task executor for the current thread
659677
///
660678
/// If none of these exist, returns the default executor.
679+
@_spi(CustomDefaultExecutors)
661680
@available(StdlibDeploymentTarget 6.2, *)
662681
@_unavailableInEmbedded
663682
public static var currentExecutor: any Executor {
@@ -672,6 +691,7 @@ extension Task where Success == Never, Failure == Never {
672691
}
673692

674693
/// Get the preferred executor for the current `Task`, if any.
694+
@_spi(CustomDefaultExecutors)
675695
@available(StdlibDeploymentTarget 6.2, *)
676696
public static var preferredExecutor: (any TaskExecutor)? {
677697
if let taskExecutor = unsafe _getPreferredTaskExecutor().asTaskExecutor() {
@@ -684,6 +704,7 @@ extension Task where Success == Never, Failure == Never {
684704
///
685705
/// This follows the same logic as `currentExecutor`, except that it ignores
686706
/// any executor that isn't a `SchedulableExecutor`.
707+
@_spi(CustomDefaultExecutors)
687708
@available(StdlibDeploymentTarget 6.2, *)
688709
@_unavailableInEmbedded
689710
public static var currentSchedulableExecutor: (any SchedulableExecutor)? {
@@ -760,6 +781,7 @@ public struct UnownedSerialExecutor: Sendable {
760781

761782
/// Automatically opt-in to complex equality semantics if the Executor
762783
/// implements `Equatable`.
784+
@_spi(CustomDefaultExecutors)
763785
@available(SwiftStdlib 6.2, *)
764786
@inlinable
765787
public init<E: SerialExecutor>(_ executor: __shared E) {
@@ -776,6 +798,7 @@ public struct UnownedSerialExecutor: Sendable {
776798
unsafe _executor_isComplexEquality(self)
777799
}
778800

801+
@_spi(CustomDefaultExecutors)
779802
@available(StdlibDeploymentTarget 6.2, *)
780803
public func asSerialExecutor() -> (any SerialExecutor)? {
781804
return unsafe unsafeBitCast(executor, to: (any SerialExecutor)?.self)
@@ -807,12 +830,14 @@ public struct UnownedTaskExecutor: Sendable {
807830
unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
808831
}
809832

833+
@_spi(CustomDefaultExecutors)
810834
@available(SwiftStdlib 6.2, *)
811835
@inlinable
812836
public init<E: TaskExecutor>(_ executor: __shared E) {
813837
unsafe self.executor = Builtin.buildOrdinaryTaskExecutorRef(executor)
814838
}
815839

840+
@_spi(CustomDefaultExecutors)
816841
@available(StdlibDeploymentTarget 6.2, *)
817842
public func asTaskExecutor() -> (any TaskExecutor)? {
818843
return unsafe unsafeBitCast(executor, to: (any TaskExecutor)?.self)

stdlib/public/Concurrency/PlatformExecutorCooperative.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import Swift
1414

1515
// This platform uses a single, global, CooperativeExecutor
16+
@_spi(CustomDefaultExecutors)
1617
@available(StdlibDeploymentTarget 6.2, *)
1718
public struct PlatformExecutorFactory: ExecutorFactory {
1819
static let executor = CooperativeExecutor()

0 commit comments

Comments
 (0)