@@ -174,19 +174,28 @@ impl AndroidApp {
174174 }
175175}
176176
177+ // Wrapper around the raw android_app pointer that can be safely sent across threads.
178+ // SAFETY: The android_app pointer is managed by the GameActivity glue code and protected
179+ // by a Mutex. Access is synchronized and the pointer is cleared on APP_CMD_DESTROY.
180+ // The Mutex wrapper provides Sync, so we only need to implement Send.
181+ #[ derive( Debug ) ]
182+ struct SendAndroidApp ( * mut ffi:: android_app ) ;
183+
184+ unsafe impl Send for SendAndroidApp { }
185+
177186#[ derive( Debug , Clone ) ]
178187struct GameActivityGlue {
179- game_activity_app : Arc < Mutex < * mut ffi :: android_app > > ,
188+ game_activity_app : Arc < Mutex < SendAndroidApp > > ,
180189}
181190
182191impl GameActivityGlue {
183192 fn new ( game_activity_app : * mut ffi:: android_app ) -> Self {
184193 Self {
185- game_activity_app : Arc :: new ( Mutex :: new ( game_activity_app) ) ,
194+ game_activity_app : Arc :: new ( Mutex :: new ( SendAndroidApp ( game_activity_app) ) ) ,
186195 }
187196 }
188197
189- fn locked_app ( & self ) -> std:: sync:: MutexGuard < ' _ , * mut ffi :: android_app > {
198+ fn locked_app ( & self ) -> std:: sync:: MutexGuard < ' _ , SendAndroidApp > {
190199 self . game_activity_app . lock ( ) . unwrap ( )
191200 }
192201
@@ -203,15 +212,15 @@ impl GameActivityGlue {
203212 F : FnOnce ( * mut ffi:: android_app ) -> R ,
204213 {
205214 let app = self . locked_app ( ) ;
206- f ( * app)
215+ f ( app. 0 )
207216 }
208217
209218 /// Called when handling the `APP_CMD_DESTROY` event to clear our retained
210219 /// pointer to the GameActivity `android_app` glue so that we don't
211220 /// accidentally access it after it's been freed.
212221 fn clear_app ( & self ) {
213222 let mut app = self . locked_app ( ) ;
214- * app = ptr:: null_mut ( ) ;
223+ app. 0 = ptr:: null_mut ( ) ;
215224 }
216225}
217226
0 commit comments