@@ -199,6 +199,18 @@ impl NativeActivityGlue {
199199 }
200200}
201201
202+ /// The status of the native thread that's created to run
203+ /// `android_main`
204+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
205+ pub enum NativeThreadState {
206+ /// The `android_main` thread hasn't been created yet
207+ Init ,
208+ /// The `android_main` thread has been spawned and started running
209+ Running ,
210+ /// The `android_main` thread has finished
211+ Stopped ,
212+ }
213+
202214#[ derive( Debug ) ]
203215pub struct NativeActivityState {
204216 pub msg_read : libc:: c_int ,
@@ -210,8 +222,11 @@ pub struct NativeActivityState {
210222 pub content_rect : ndk_sys:: ARect ,
211223 pub activity_state : State ,
212224 pub destroy_requested : bool ,
213- pub running : bool ,
225+ pub thread_state : NativeThreadState ,
214226 pub app_has_saved_state : bool ,
227+
228+ /// Set as soon as the Java main thread notifies us of an
229+ /// `onDestroyed` callback.
215230 pub destroyed : bool ,
216231 pub redraw_needed : bool ,
217232 pub pending_input_queue : * mut ndk_sys:: AInputQueue ,
@@ -303,8 +318,6 @@ impl Drop for WaitableNativeActivityState {
303318 unsafe {
304319 let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
305320 guard. detach_input_queue_from_looper ( ) ;
306- guard. destroyed = true ;
307- self . cond . notify_one ( ) ;
308321 }
309322 }
310323}
@@ -356,7 +369,7 @@ impl WaitableNativeActivityState {
356369 content_rect : Rect :: empty ( ) . into ( ) ,
357370 activity_state : State :: Init ,
358371 destroy_requested : false ,
359- running : false ,
372+ thread_state : NativeThreadState :: Init ,
360373 app_has_saved_state : false ,
361374 destroyed : false ,
362375 redraw_needed : false ,
@@ -369,10 +382,11 @@ impl WaitableNativeActivityState {
369382
370383 pub fn notify_destroyed ( & self ) {
371384 let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
385+ guard. destroyed = true ;
372386
373387 unsafe {
374388 guard. write_cmd ( AppCmd :: Destroy ) ;
375- while ! guard. destroyed {
389+ while guard. thread_state != NativeThreadState :: Stopped {
376390 guard = self . cond . wait ( guard) . unwrap ( ) ;
377391 }
378392
@@ -541,7 +555,13 @@ impl WaitableNativeActivityState {
541555
542556 pub fn notify_main_thread_running ( & self ) {
543557 let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
544- guard. running = true ;
558+ guard. thread_state = NativeThreadState :: Running ;
559+ self . cond . notify_one ( ) ;
560+ }
561+
562+ pub fn notify_main_thread_stopped_running ( & self ) {
563+ let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
564+ guard. thread_state = NativeThreadState :: Stopped ;
545565 self . cond . notify_one ( ) ;
546566 }
547567
@@ -907,11 +927,16 @@ extern "C" fn ANativeActivity_onCreate(
907927
908928 ndk_context:: release_android_context ( ) ;
909929 }
930+
931+ rust_glue. notify_main_thread_stopped_running ( ) ;
910932 } ) ;
911933
912934 // Wait for thread to start.
913935 let mut guard = jvm_glue. mutex . lock ( ) . unwrap ( ) ;
914- while !guard. running {
936+
937+ // Don't specifically wait for `Running` just in case `android_main` returns
938+ // immediately and the state is set to `Stopped`
939+ while guard. thread_state == NativeThreadState :: Init {
915940 guard = jvm_glue. cond . wait ( guard) . unwrap ( ) ;
916941 }
917942 } )
0 commit comments