Skip to content

Commit 0b63037

Browse files
Split out the letacy hook-based global task executor
1 parent 8c8e0eb commit 0b63037

File tree

2 files changed

+110
-98
lines changed

2 files changed

+110
-98
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import _CJavaScriptEventLoop
2+
import _CJavaScriptKit
3+
4+
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
5+
extension JavaScriptEventLoop {
6+
7+
static func installByLegacyHook() {
8+
#if compiler(>=5.9)
9+
typealias swift_task_asyncMainDrainQueue_hook_Fn = @convention(thin) (
10+
swift_task_asyncMainDrainQueue_original, swift_task_asyncMainDrainQueue_override
11+
) -> Void
12+
let swift_task_asyncMainDrainQueue_hook_impl: swift_task_asyncMainDrainQueue_hook_Fn = { _, _ in
13+
swjs_unsafe_event_loop_yield()
14+
}
15+
swift_task_asyncMainDrainQueue_hook = unsafeBitCast(
16+
swift_task_asyncMainDrainQueue_hook_impl,
17+
to: UnsafeMutableRawPointer?.self
18+
)
19+
#endif
20+
21+
typealias swift_task_enqueueGlobal_hook_Fn = @convention(thin) (UnownedJob, swift_task_enqueueGlobal_original)
22+
-> Void
23+
let swift_task_enqueueGlobal_hook_impl: swift_task_enqueueGlobal_hook_Fn = { job, original in
24+
JavaScriptEventLoop.shared.unsafeEnqueue(job)
25+
}
26+
swift_task_enqueueGlobal_hook = unsafeBitCast(
27+
swift_task_enqueueGlobal_hook_impl,
28+
to: UnsafeMutableRawPointer?.self
29+
)
30+
31+
typealias swift_task_enqueueGlobalWithDelay_hook_Fn = @convention(thin) (
32+
UInt64, UnownedJob, swift_task_enqueueGlobalWithDelay_original
33+
) -> Void
34+
let swift_task_enqueueGlobalWithDelay_hook_impl: swift_task_enqueueGlobalWithDelay_hook_Fn = {
35+
delay,
36+
job,
37+
original in
38+
JavaScriptEventLoop.shared.enqueue(job, withDelay: delay)
39+
}
40+
swift_task_enqueueGlobalWithDelay_hook = unsafeBitCast(
41+
swift_task_enqueueGlobalWithDelay_hook_impl,
42+
to: UnsafeMutableRawPointer?.self
43+
)
44+
45+
#if compiler(>=5.7)
46+
typealias swift_task_enqueueGlobalWithDeadline_hook_Fn = @convention(thin) (
47+
Int64, Int64, Int64, Int64, Int32, UnownedJob, swift_task_enqueueGlobalWithDelay_original
48+
) -> Void
49+
let swift_task_enqueueGlobalWithDeadline_hook_impl: swift_task_enqueueGlobalWithDeadline_hook_Fn = {
50+
sec,
51+
nsec,
52+
tsec,
53+
tnsec,
54+
clock,
55+
job,
56+
original in
57+
JavaScriptEventLoop.shared.enqueue(job, withDelay: sec, nsec, tsec, tnsec, clock)
58+
}
59+
swift_task_enqueueGlobalWithDeadline_hook = unsafeBitCast(
60+
swift_task_enqueueGlobalWithDeadline_hook_impl,
61+
to: UnsafeMutableRawPointer?.self
62+
)
63+
#endif
64+
65+
typealias swift_task_enqueueMainExecutor_hook_Fn = @convention(thin) (
66+
UnownedJob, swift_task_enqueueMainExecutor_original
67+
) -> Void
68+
let swift_task_enqueueMainExecutor_hook_impl: swift_task_enqueueMainExecutor_hook_Fn = { job, original in
69+
JavaScriptEventLoop.shared.unsafeEnqueue(job)
70+
}
71+
swift_task_enqueueMainExecutor_hook = unsafeBitCast(
72+
swift_task_enqueueMainExecutor_hook_impl,
73+
to: UnsafeMutableRawPointer?.self
74+
)
75+
76+
}
77+
}
78+
79+
80+
#if compiler(>=5.7)
81+
/// Taken from https://github.com/apple/swift/blob/d375c972f12128ec6055ed5f5337bfcae3ec67d8/stdlib/public/Concurrency/Clock.swift#L84-L88
82+
@_silgen_name("swift_get_time")
83+
internal func swift_get_time(
84+
_ seconds: UnsafeMutablePointer<Int64>,
85+
_ nanoseconds: UnsafeMutablePointer<Int64>,
86+
_ clock: CInt
87+
)
88+
89+
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
90+
extension JavaScriptEventLoop {
91+
fileprivate func enqueue(
92+
_ job: UnownedJob,
93+
withDelay seconds: Int64,
94+
_ nanoseconds: Int64,
95+
_ toleranceSec: Int64,
96+
_ toleranceNSec: Int64,
97+
_ clock: Int32
98+
) {
99+
var nowSec: Int64 = 0
100+
var nowNSec: Int64 = 0
101+
swift_get_time(&nowSec, &nowNSec, clock)
102+
let delayNanosec = (seconds - nowSec) * 1_000_000_000 + (nanoseconds - nowNSec)
103+
enqueue(job, withDelay: delayNanosec <= 0 ? 0 : UInt64(delayNanosec))
104+
}
105+
}
106+
#endif
107+

Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift

Lines changed: 3 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -119,77 +119,10 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
119119
private static func installGlobalExecutorIsolated() {
120120
guard !didInstallGlobalExecutor else { return }
121121
didInstallGlobalExecutor = true
122-
123-
#if compiler(>=5.9)
124-
typealias swift_task_asyncMainDrainQueue_hook_Fn = @convention(thin) (
125-
swift_task_asyncMainDrainQueue_original, swift_task_asyncMainDrainQueue_override
126-
) -> Void
127-
let swift_task_asyncMainDrainQueue_hook_impl: swift_task_asyncMainDrainQueue_hook_Fn = { _, _ in
128-
swjs_unsafe_event_loop_yield()
129-
}
130-
swift_task_asyncMainDrainQueue_hook = unsafeBitCast(
131-
swift_task_asyncMainDrainQueue_hook_impl,
132-
to: UnsafeMutableRawPointer?.self
133-
)
134-
#endif
135-
136-
typealias swift_task_enqueueGlobal_hook_Fn = @convention(thin) (UnownedJob, swift_task_enqueueGlobal_original)
137-
-> Void
138-
let swift_task_enqueueGlobal_hook_impl: swift_task_enqueueGlobal_hook_Fn = { job, original in
139-
JavaScriptEventLoop.shared.unsafeEnqueue(job)
140-
}
141-
swift_task_enqueueGlobal_hook = unsafeBitCast(
142-
swift_task_enqueueGlobal_hook_impl,
143-
to: UnsafeMutableRawPointer?.self
144-
)
145-
146-
typealias swift_task_enqueueGlobalWithDelay_hook_Fn = @convention(thin) (
147-
UInt64, UnownedJob, swift_task_enqueueGlobalWithDelay_original
148-
) -> Void
149-
let swift_task_enqueueGlobalWithDelay_hook_impl: swift_task_enqueueGlobalWithDelay_hook_Fn = {
150-
delay,
151-
job,
152-
original in
153-
JavaScriptEventLoop.shared.enqueue(job, withDelay: delay)
154-
}
155-
swift_task_enqueueGlobalWithDelay_hook = unsafeBitCast(
156-
swift_task_enqueueGlobalWithDelay_hook_impl,
157-
to: UnsafeMutableRawPointer?.self
158-
)
159-
160-
#if compiler(>=5.7)
161-
typealias swift_task_enqueueGlobalWithDeadline_hook_Fn = @convention(thin) (
162-
Int64, Int64, Int64, Int64, Int32, UnownedJob, swift_task_enqueueGlobalWithDelay_original
163-
) -> Void
164-
let swift_task_enqueueGlobalWithDeadline_hook_impl: swift_task_enqueueGlobalWithDeadline_hook_Fn = {
165-
sec,
166-
nsec,
167-
tsec,
168-
tnsec,
169-
clock,
170-
job,
171-
original in
172-
JavaScriptEventLoop.shared.enqueue(job, withDelay: sec, nsec, tsec, tnsec, clock)
173-
}
174-
swift_task_enqueueGlobalWithDeadline_hook = unsafeBitCast(
175-
swift_task_enqueueGlobalWithDeadline_hook_impl,
176-
to: UnsafeMutableRawPointer?.self
177-
)
178-
#endif
179-
180-
typealias swift_task_enqueueMainExecutor_hook_Fn = @convention(thin) (
181-
UnownedJob, swift_task_enqueueMainExecutor_original
182-
) -> Void
183-
let swift_task_enqueueMainExecutor_hook_impl: swift_task_enqueueMainExecutor_hook_Fn = { job, original in
184-
JavaScriptEventLoop.shared.unsafeEnqueue(job)
185-
}
186-
swift_task_enqueueMainExecutor_hook = unsafeBitCast(
187-
swift_task_enqueueMainExecutor_hook_impl,
188-
to: UnsafeMutableRawPointer?.self
189-
)
122+
installByLegacyHook()
190123
}
191124

192-
private func enqueue(_ job: UnownedJob, withDelay nanoseconds: UInt64) {
125+
internal func enqueue(_ job: UnownedJob, withDelay nanoseconds: UInt64) {
193126
let milliseconds = nanoseconds / 1_000_000
194127
setTimeout(
195128
Double(milliseconds),
@@ -203,7 +136,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
203136
)
204137
}
205138

206-
private func unsafeEnqueue(_ job: UnownedJob) {
139+
internal func unsafeEnqueue(_ job: UnownedJob) {
207140
#if canImport(wasi_pthread) && compiler(>=6.1) && _runtime(_multithreaded)
208141
guard swjs_get_worker_thread_id_cached() == SWJS_MAIN_THREAD_ID else {
209142
// Notify the main thread to execute the job when a job is
@@ -237,34 +170,6 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
237170
}
238171
}
239172

240-
#if compiler(>=5.7)
241-
/// Taken from https://github.com/apple/swift/blob/d375c972f12128ec6055ed5f5337bfcae3ec67d8/stdlib/public/Concurrency/Clock.swift#L84-L88
242-
@_silgen_name("swift_get_time")
243-
internal func swift_get_time(
244-
_ seconds: UnsafeMutablePointer<Int64>,
245-
_ nanoseconds: UnsafeMutablePointer<Int64>,
246-
_ clock: CInt
247-
)
248-
249-
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
250-
extension JavaScriptEventLoop {
251-
fileprivate func enqueue(
252-
_ job: UnownedJob,
253-
withDelay seconds: Int64,
254-
_ nanoseconds: Int64,
255-
_ toleranceSec: Int64,
256-
_ toleranceNSec: Int64,
257-
_ clock: Int32
258-
) {
259-
var nowSec: Int64 = 0
260-
var nowNSec: Int64 = 0
261-
swift_get_time(&nowSec, &nowNSec, clock)
262-
let delayNanosec = (seconds - nowSec) * 1_000_000_000 + (nanoseconds - nowNSec)
263-
enqueue(job, withDelay: delayNanosec <= 0 ? 0 : UInt64(delayNanosec))
264-
}
265-
}
266-
#endif
267-
268173
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
269174
extension JSPromise {
270175
/// Wait for the promise to complete, returning (or throwing) its result.

0 commit comments

Comments
 (0)