@@ -36,8 +36,6 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
36
36
public static let invalid = Events ( rawValue: 1 << 4 )
37
37
}
38
38
39
- public typealias Callback = @convention ( c) ( CInt , CInt , UnsafeMutableRawPointer ? ) -> CInt
40
-
41
39
private let _looper : OpaquePointer
42
40
43
41
public init ( wrapping looper: OpaquePointer ) {
@@ -67,7 +65,7 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
67
65
}
68
66
69
67
/// Adds a new file descriptor to be polled by the looper.
70
- public func add( fd: FileDescriptor , ident: CInt = 0 , events: Events = . input, callback: Callback ? = nil , data: UnsafeMutableRawPointer ? = nil ) throws {
68
+ public func add( fd: FileDescriptor , ident: CInt = 0 , events: Events = . input, callback: LooperCallback ? = nil , data: UnsafeMutableRawPointer ? = nil ) throws {
71
69
if ALooper_addFd ( _looper, fd. rawValue, callback != nil ? CInt ( ALOOPER_POLL_CALLBACK) : ident, events. rawValue, callback, data) != 1 {
72
70
throw LooperError . addFdFailure
73
71
}
@@ -132,6 +130,8 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
132
130
}
133
131
}
134
132
133
+ public typealias LooperCallback = @convention ( c) ( CInt , CInt , UnsafeMutableRawPointer ? ) -> CInt
134
+
135
135
private var _mainLooper : OpaquePointer ?
136
136
137
137
public extension AndroidLooper {
@@ -263,55 +263,31 @@ private extension AndroidMainActor {
263
263
guard !didInstallGlobalExecutor else { return }
264
264
didInstallGlobalExecutor = true
265
265
266
- // typealias swift_task_enqueueGlobal_hook_Fn = @convention(thin) (UnsafeMutablePointer<Job>, swift_task_enqueueGlobal_original) -> Void
267
- // let swift_task_enqueueGlobal_hook_impl: swift_task_enqueueGlobal_hook_Fn = { job, original in
268
- // logger.info("### swift_task_enqueueGlobal_hook_impl: job: \(job.pointee)")
269
- //
270
- //// let flags = job.pointee.Flags
271
- //// let unownedJob = unsafeBitCast(job.pointee, to: UnownedJob.self) // Fatal error: Can't unsafeBitCast between types of different sizes
272
- //// logger.info("### swift_task_enqueueGlobal_hook_impl: unownedJob: \(unownedJob)")
273
- //
274
- // //AndroidMainActor._executor.enqueue(unownedJob)
275
- //
276
- // original(job)
277
- // try! AndroidMainActor._executor.signal()
278
- // }
279
- // swift_task_enqueueGlobal_hook = unsafeBitCast(swift_task_enqueueGlobal_hook_impl, to: UnsafeMutableRawPointer?.self)
280
-
281
- // // this would be a better way to signal the main looper, but unfortunately it is never called: https://github.com/swiftlang/swift/issues/63104
282
- // typealias swift_task_enqueueMainExecutor_hook_Fn = @convention(thin) (UnsafeMutablePointer<Job>, swift_task_enqueueMainExecutor_original) -> Void
283
- // let swift_task_enqueueMainExecutor_hook_impl: swift_task_enqueueMainExecutor_hook_Fn = { job, original in
284
- // //logger.info("### swift_task_enqueueMainExecutor_hook_Fn")
285
- // original(job)
286
- // try! AndroidMainActor._executor.signal() // signal the main looper to wake a drain the main queue
287
- // }
288
- // swift_task_enqueueMainExecutor_hook = unsafeBitCast(swift_task_enqueueMainExecutor_hook_impl, to: UnsafeMutableRawPointer?.self)
289
-
290
-
291
- // typealias swift_task_enqueueGlobalWithDelay_hook_Fn = @convention(thin) (UInt64, UnsafeMutablePointer<Job>, swift_task_enqueueGlobalWithDelay_original) -> Void
292
- // let swift_task_enqueueGlobalWithDelay_hook_impl: swift_task_enqueueGlobalWithDelay_hook_Fn = { delay, job, original in
293
- // logger.info("### swift_task_enqueueGlobalWithDelay_hook_impl")
294
- // original(job)
295
- // }
296
- // swift_task_enqueueGlobalWithDelay_hook = unsafeBitCast(swift_task_enqueueGlobalWithDelay_hook_impl, to: UnsafeMutableRawPointer?.self)
297
-
298
- // #if compiler(>=5.7)
299
- // typealias swift_task_enqueueGlobalWithDeadline_hook_Fn = @convention(thin) (Int64, Int64, Int64, Int64, Int32, UnsafeMutablePointer<Job>, swift_task_enqueueGlobalWithDelay_original) -> Void
300
- // let swift_task_enqueueGlobalWithDeadline_hook_impl: swift_task_enqueueGlobalWithDeadline_hook_Fn = { sec, nsec, tsec, tnsec, clock, job, original in
301
- // logger.info("### swift_task_enqueueGlobalWithDeadline_hook_impl")
302
- // original(job)
303
- // }
304
- // swift_task_enqueueGlobalWithDeadline_hook = unsafeBitCast(swift_task_enqueueGlobalWithDeadline_hook_impl, to: UnsafeMutableRawPointer?.self)
305
- // #endif
306
- //
307
- // #if compiler(>=5.9)
308
- // typealias swift_task_asyncMainDrainQueue_hook_Fn = @convention(thin) (swift_task_asyncMainDrainQueue_original, swift_task_asyncMainDrainQueue_override) -> Void
309
- // let swift_task_asyncMainDrainQueue_hook_impl: swift_task_asyncMainDrainQueue_hook_Fn = { _, _ in
310
- // logger.info("### swift_task_asyncMainDrainQueue_hook_impl")
311
- // // _unsafe_event_loop_yield()
312
- // }
313
- // swift_task_asyncMainDrainQueue_hook = unsafeBitCast(swift_task_asyncMainDrainQueue_hook_impl, to: UnsafeMutableRawPointer?.self)
314
- // #endif
266
+
267
+ let looperCallback : LooperCallback = { ft, event, data in
268
+ while true {
269
+ switch CFRunLoopRunInMode ( kCFRunLoopDefaultMode, 0.0 , true ) {
270
+ case CFRunLoopRunResult . handledSource:
271
+ continue // continue run loop
272
+ case CFRunLoopRunResult . finished:
273
+ return 1 // continue listening for events
274
+ case CFRunLoopRunResult . stopped:
275
+ return 0 // stop listening
276
+ case CFRunLoopRunResult . timedOut:
277
+ return 1 // continue listening for events
278
+ }
279
+ }
280
+ }
281
+
282
+ let mainLoop = CFRunLoopGetMain ( )
283
+
284
+ // https://github.com/readdle/swift-android-ndk/blob/main/Sources/CAndroidNDK/MainRunLoop.c#L71
285
+ //__CFPort wakeUpPort = mainLoop->_wakeUpPort;
286
+ //int result = ALooper_addFd(_mainLooper, wakeUpPort, 0, CInt(ALOOPER_EVENT_INPUT), &looperCallback, nil)
287
+ //mainLoop->_perRunData->ignoreWakeUps = 0x0;
288
+
289
+ let dispatchPort = _dispatch_get_main_queue_port_4CF ( )
290
+ let result = ALooper_addFd ( _mainLooper, dispatchPort, 0 , CInt ( ALOOPER_EVENT_INPUT) , looperCallback, nil )
315
291
}
316
292
}
317
293
0 commit comments