Rework Event type to allow synchronized cleanup #121
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously,
NativeActivity
callbacks returned immediately after dispatching an asynchronousEvent
to the user on a UNIX pipe. This made it impossible to handle destruction callbacks (on_native_window_destroyed
,on_input_queue_destroyed
) in a manner conforming with the Android docs, which state that all cleanup must be completed before the callback returns, cf.ANativeActivityCallbacks docs
.Therefore, some method of blocking and then notifying the callback had to be introduced. In order to accomplish this, I wrote a simple wrapper on a lockless queue (
crossbeam_queue::SegQueue
) and aneventfd
object, which allows sending arbitrary Rust objects to the user while notifying the AndroidLooper
in a manner preserving the source of the notification.This enabled a different semantics of the
Event
type.Events
now transfer ownership of various Android handles (e.g.NativeActivity
,InputQueue
) to the user. The user is responsible for hanging on to these handles. When a corresponding*Destroyed
event is received, the user must ensure that they complete all cleanup before dropping the containedEventSyncGuard
object. They must not touch the relevant handle afterwards.Additionally, care is taken to prevent the user from obtaining a handle to a
NativeWindow
or anInputQueue
after a corresponding*_destroyed
callback has fired. In this case, the*Created
event will deliverNone
and no corresponding*Destroyed
event will be dispatched.This is a somewhat significant change of the public API and there are ways to make it more similar to the current version or just more ergonomic. I'm open to discussing these, as well as any performance or synchronization concerns.