@@ -54,17 +54,14 @@ public extension AndroidMainActor {
5454 // the public API should always be retained.
5555 assert ( looper. isRetained)
5656
57- let executor : Looper . Executor
57+ // override the global executors to wake the main looper to drain the queue whenever something is scheduled
5858 do {
59- executor = try Looper . Executor ( looper: looper)
59+ let executor = try Looper . Executor ( looper: looper)
60+ return try AndroidMainActor . installGlobalExecutor ( executor)
6061 }
6162 catch {
62- assertionFailure ( " Unable to initialize Looper.Executor: \( error) " )
6363 return false
6464 }
65-
66- // override the global executors to wake the main looper to drain the queue whenever something is scheduled
67- return AndroidMainActor . installGlobalExecutor ( executor)
6865 }
6966}
7067
@@ -96,13 +93,13 @@ private extension AndroidMainActor {
9693 /// See also [a draft proposal for custom executors](https://github.com/rjmccall/swift-evolution/blob/custom-executors/proposals/0000-custom-executors.md#the-default-global-concurrent-executor)
9794 static func installGlobalExecutor(
9895 _ executor: Looper . Executor
99- ) -> Bool {
96+ ) throws ( AndroidLooperError ) -> Bool {
10097 if didInstallGlobalExecutor {
10198 return false
10299 }
103100 didInstallGlobalExecutor = true
104101
105- let looperCallback : Looper . Callback = { ft, event, data in
102+ let looperCallback : Looper . Handle . Callback = { ft, event, data in
106103 while true {
107104 switch CFRunLoopRunInMode ( kCFRunLoopDefaultMode, 0.0 , true ) {
108105 case CFRunLoopRunResult . handledSource:
@@ -123,66 +120,17 @@ private extension AndroidMainActor {
123120 let dispatchPort = _dispatch_get_main_queue_port_4CF ( )
124121 let fileDescriptor = FileDescriptor ( rawValue: dispatchPort)
125122
126- guard executor. looper. handle. add (
123+ try executor. looper. handle. add (
127124 fileDescriptor: fileDescriptor,
128125 id: 0 ,
129126 events: . input,
130127 callback: looperCallback,
131128 data: nil
132- ) else {
133- return false
134- }
129+ ) . get ( )
130+
135131 // install executor
136132 self . executor = executor
137133 _ = mainLoop
138134 return true
139135 }
140136}
141-
142- @available ( macOS 13 . 0 , * )
143- internal extension Looper . Handle {
144-
145- /// Waits for events to be available, with optional timeout in milliseconds.
146- func pollOnce( duration: Duration ? = nil ) throws ( Error) -> AndroidMainActor . PollResult ? {
147- var outFd : CInt = - 1
148- var outEvents : CInt = 0
149- var outData : UnsafeMutableRawPointer ?
150-
151- let timeoutMillis : CInt
152- if let duration {
153- timeoutMillis = CInt ( duration. milliseconds)
154- } else {
155- timeoutMillis = 0
156- }
157-
158- let err = ALooper_pollOnce ( timeoutMillis, & outFd, & outEvents, & outData)
159- switch Int ( err) {
160- case ALOOPER_POLL_WAKE:
161- fallthrough
162- case ALOOPER_POLL_CALLBACK:
163- return nil
164- case ALOOPER_POLL_TIMEOUT:
165- throw AndroidMainActor . Error. pollTimeout
166- case ALOOPER_POLL_ERROR:
167- throw AndroidMainActor . Error. pollError
168- default :
169- return AndroidMainActor . PollResult ( id: err, fd: . init( rawValue: outFd) , events: Looper . Events ( rawValue: Int ( outEvents) ) , data: outData)
170- }
171- }
172- }
173-
174- @available ( macOS 13 . 0 , * )
175- public extension AndroidMainActor {
176-
177- enum Error : Swift . Error {
178- case pollTimeout
179- case pollError
180- }
181-
182- struct PollResult : Identifiable {
183- public let id : CInt
184- public let fd : FileDescriptor
185- public let events : Looper . Events
186- public let data : UnsafeRawPointer ?
187- }
188- }
0 commit comments