Skip to content

Commit 74ed711

Browse files
committed
Use _dispatch_get_main_queue_port_4CF for @mainactor and DispatchQueue.main support
1 parent ae23266 commit 74ed711

File tree

1 file changed

+28
-52
lines changed

1 file changed

+28
-52
lines changed

Sources/AndroidLooper/AndroidLooper.swift

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
135135
private var _mainLooper: OpaquePointer?
136136

137137
public 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

Comments
 (0)