Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
target: "wasm32-unknown-wasip1"
- os: ubuntu-24.04
toolchain:
download-url: https://download.swift.org/swift-6.3-branch/ubuntu2404/swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-05-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-05-a-ubuntu24.04.tar.gz
download-url: https://download.swift.org/swift-6.3-branch/ubuntu2404/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a-ubuntu24.04.tar.gz
wasi-backend: Node
target: "wasm32-unknown-wasip1"
- os: ubuntu-22.04
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// See: https://forums.swift.org/t/pitch-2-custom-main-and-global-executors/78437

#if compiler(>=6.3)
@_spi(ExperimentalCustomExecutors) import _Concurrency
@_spi(ExperimentalCustomExecutors) @_spi(ExperimentalScheduling) import _Concurrency
#else
import _Concurrency
#endif
Expand Down Expand Up @@ -42,20 +42,29 @@ extension JavaScriptEventLoop: SchedulingExecutor {
) {
let duration: Duration
// Handle clocks we know
#if !hasFeature(Embedded)
if let _ = clock as? ContinuousClock {
duration = delay as! ContinuousClock.Duration
} else if let _ = clock as? SuspendingClock {
duration = delay as! SuspendingClock.Duration
} else {
// Hand-off the scheduling work to Clock implementation for unknown clocks
#if compiler(>=6.4)
// Hand-off the scheduling work to Clock implementation for unknown clocks.
// Clock.enqueue is only available in the development branch (6.4+).
clock.enqueue(
Comment thread
MaxDesiatov marked this conversation as resolved.
job,
on: self,
at: clock.now.advanced(by: delay),
tolerance: tolerance
)
return
#else
fatalError("Unsupported clock type; only ContinuousClock and SuspendingClock are supported")
#endif
}
#else
fatalError("SchedulingExecutor.enqueue is not supported in embedded mode")
#endif
let milliseconds = Self.delayInMilliseconds(from: duration)
self.enqueue(
UnownedJob(job),
Expand All @@ -81,6 +90,7 @@ extension JavaScriptEventLoop: ExecutorFactory {
JavaScriptEventLoop.shared.enqueue(job)
}

#if !hasFeature(Embedded)
func enqueue<C: Clock>(
_ job: consuming ExecutorJob,
after delay: C.Duration,
Expand All @@ -94,6 +104,7 @@ extension JavaScriptEventLoop: ExecutorFactory {
clock: clock
)
}
#endif
func run() throws {
try JavaScriptEventLoop.shared.run()
}
Expand Down
7 changes: 5 additions & 2 deletions Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,16 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
private static func installGlobalExecutorIsolated() {
guard !didInstallGlobalExecutor else { return }
didInstallGlobalExecutor = true
#if compiler(>=6.3)
#if compiler(>=6.3) && !hasFeature(Embedded)
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, visionOS 9999, *) {
// For Swift 6.3 and above, we can use the new `ExecutorFactory` API
_Concurrency._createExecutors(factory: JavaScriptEventLoop.self)
}
#else
// For Swift 6.1 and below, we need to install the global executor by hook API
// For Swift 6.1 and below, or Embedded Swift, we need to install
// the global executor by hook API. The ExecutorFactory mechanism
// does not work in Embedded Swift because ExecutorImpl.swift is
// excluded from the embedded Concurrency library.
installByLegacyHook()
#endif
}
Expand Down
Loading