@@ -199,6 +199,18 @@ impl NativeActivityGlue {
199
199
}
200
200
}
201
201
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
+
202
214
#[ derive( Debug ) ]
203
215
pub struct NativeActivityState {
204
216
pub msg_read : libc:: c_int ,
@@ -210,8 +222,11 @@ pub struct NativeActivityState {
210
222
pub content_rect : ndk_sys:: ARect ,
211
223
pub activity_state : State ,
212
224
pub destroy_requested : bool ,
213
- pub running : bool ,
225
+ pub thread_state : NativeThreadState ,
214
226
pub app_has_saved_state : bool ,
227
+
228
+ /// Set as soon as the Java main thread notifies us of an
229
+ /// `onDestroyed` callback.
215
230
pub destroyed : bool ,
216
231
pub redraw_needed : bool ,
217
232
pub pending_input_queue : * mut ndk_sys:: AInputQueue ,
@@ -303,8 +318,6 @@ impl Drop for WaitableNativeActivityState {
303
318
unsafe {
304
319
let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
305
320
guard. detach_input_queue_from_looper ( ) ;
306
- guard. destroyed = true ;
307
- self . cond . notify_one ( ) ;
308
321
}
309
322
}
310
323
}
@@ -356,7 +369,7 @@ impl WaitableNativeActivityState {
356
369
content_rect : Rect :: empty ( ) . into ( ) ,
357
370
activity_state : State :: Init ,
358
371
destroy_requested : false ,
359
- running : false ,
372
+ thread_state : NativeThreadState :: Init ,
360
373
app_has_saved_state : false ,
361
374
destroyed : false ,
362
375
redraw_needed : false ,
@@ -369,10 +382,11 @@ impl WaitableNativeActivityState {
369
382
370
383
pub fn notify_destroyed ( & self ) {
371
384
let mut guard = self . mutex . lock ( ) . unwrap ( ) ;
385
+ guard. destroyed = true ;
372
386
373
387
unsafe {
374
388
guard. write_cmd ( AppCmd :: Destroy ) ;
375
- while ! guard. destroyed {
389
+ while guard. thread_state != NativeThreadState :: Stopped {
376
390
guard = self . cond . wait ( guard) . unwrap ( ) ;
377
391
}
378
392
@@ -541,7 +555,13 @@ impl WaitableNativeActivityState {
541
555
542
556
pub fn notify_main_thread_running ( & self ) {
543
557
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 ;
545
565
self . cond . notify_one ( ) ;
546
566
}
547
567
@@ -907,11 +927,16 @@ extern "C" fn ANativeActivity_onCreate(
907
927
908
928
ndk_context:: release_android_context ( ) ;
909
929
}
930
+
931
+ rust_glue. notify_main_thread_stopped_running ( ) ;
910
932
} ) ;
911
933
912
934
// Wait for thread to start.
913
935
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 {
915
940
guard = jvm_glue. cond . wait ( guard) . unwrap ( ) ;
916
941
}
917
942
} )
0 commit comments