native_activity: Only wait for state to update while main thread is running #187
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.
We see that some Android callbacks like
onStart()
deadlock, specifically when returning out of the main thread before running any event loop (but likely also whenever terminating the event loop), because they don't check if the thread is still even running and are otherwise guaranteed receive anactivity_state
update or other state change to unblock themselves.This is a followup to #94 which only concerned itself with a deadlock caused by a destructor not running because that very object was kept alive to poll on the
destroyed
field that destructor was supposed to set, but its newthread_state
can be reused to disable these condvar waits when the "sending" thread has disappeared.Separately, that PR mentions
Activity
recreates because of configuration changes which isn't supported anyway becauseActivity
is still wrongly assumed to be a global singleton (I am still working on fixing all this 🤞!).Note that I'm not at all going to claim this to be really fixing anything, it's more of a bandaid on top of another bandaid with doubts if it'll stick.
#94 seems to have only considered thread state, which makes sense given that
finish()
is also unconditionally called when the "main" thread created byandroid-activity
returns, but the mentioned missingdrop()
handling ofWaitableNativeActivityState
also seems to very specifically exist becauseAndroidApp
is explicitly and intentionally cheaplyClone
able andSend
/Sync
. If anything the user could move things to a different thread to handle their looping behaviour there. Liveness of these objects is an indicator that the user may/will still poll elsewhere, or at least has the ability to. That should likely have been the predicate to exit out of variouswhile
loops rather than the thread state, but here we are.Add to that the request to not start a thread for the user in the first place (requires a redesign to signify that users must timely return from their not-really-
main()
-anymore), so that they can load things fromJNIEnv
which uses prior Java stackframes to resolve classes that cannot otherwise be found without poking atContext.getClassLoader()
...