Skip to content

native_activity: Only wait for state to update while main thread is running #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions android-activity/src/native_activity/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,9 @@ impl WaitableNativeActivityState {

guard.pending_input_queue = input_queue;
guard.write_cmd(AppCmd::InputQueueChanged);
while guard.input_queue != guard.pending_input_queue {
while guard.thread_state == NativeThreadState::Running
&& guard.input_queue != guard.pending_input_queue
{
guard = self.cond.wait(guard).unwrap();
}
guard.pending_input_queue = ptr::null_mut();
Expand All @@ -468,7 +470,9 @@ impl WaitableNativeActivityState {
if guard.pending_window.is_some() {
guard.write_cmd(AppCmd::InitWindow);
}
while guard.window != guard.pending_window {
while guard.thread_state == NativeThreadState::Running
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess all of these (maybe with an exception for input events) should probably be checking for != NativeThreadState::Stopped so that callbacks effectively buffer during initialization and allow the app to start handling events or else exit and have this transition to Stopped.

The protocol for notifying the app about a window is supposed to be synchronous and it would be a significant change to have these start being async until the thread is initialized and 'running'.

&& guard.window != guard.pending_window
{
guard = self.cond.wait(guard).unwrap();
}
guard.pending_window = None;
Expand All @@ -492,7 +496,7 @@ impl WaitableNativeActivityState {
};
guard.write_cmd(cmd);

while guard.activity_state != state {
while guard.thread_state == NativeThreadState::Running && guard.activity_state != state {
guard = self.cond.wait(guard).unwrap();
}
}
Expand All @@ -505,7 +509,7 @@ impl WaitableNativeActivityState {
// this to be None
debug_assert!(!guard.app_has_saved_state, "SaveState request clash");
guard.write_cmd(AppCmd::SaveState);
while !guard.app_has_saved_state {
while guard.thread_state == NativeThreadState::Running && !guard.app_has_saved_state {
guard = self.cond.wait(guard).unwrap();
}
guard.app_has_saved_state = false;
Expand Down Expand Up @@ -560,7 +564,9 @@ impl WaitableNativeActivityState {
pub fn notify_main_thread_stopped_running(&self) {
let mut guard = self.mutex.lock().unwrap();
guard.thread_state = NativeThreadState::Stopped;
self.cond.notify_one();
// Notify all waiters to unblock any Android callbacks that would otherwise be waiting
// indefinitely for the now-stopped (!) main thread.
self.cond.notify_all();
}

pub unsafe fn pre_exec_cmd(
Expand Down