@@ -36,8 +36,6 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
3636 public static let invalid = Events ( rawValue: 1 << 4 )
3737 }
3838
39- public typealias Callback = @convention ( c) ( CInt , CInt , UnsafeMutableRawPointer ? ) -> CInt
40-
4139 private let _looper : OpaquePointer
4240
4341 public init ( wrapping looper: OpaquePointer ) {
@@ -67,7 +65,7 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
6765 }
6866
6967 /// 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 {
7169 if ALooper_addFd ( _looper, fd. rawValue, callback != nil ? CInt ( ALOOPER_POLL_CALLBACK) : ident, events. rawValue, callback, data) != 1 {
7270 throw LooperError . addFdFailure
7371 }
@@ -132,6 +130,8 @@ public struct AndroidLooper: ~Copyable, @unchecked Sendable {
132130 }
133131}
134132
133+ public typealias LooperCallback = @convention ( c) ( CInt , CInt , UnsafeMutableRawPointer ? ) -> CInt
134+
135135private var _mainLooper : OpaquePointer ?
136136
137137public extension AndroidLooper {
@@ -263,55 +263,31 @@ private extension AndroidMainActor {
263263 guard !didInstallGlobalExecutor else { return }
264264 didInstallGlobalExecutor = true
265265
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 )
315291 }
316292}
317293
0 commit comments