Skip to content

Commit ca87ad8

Browse files
authored
Notify event pipe before releasing NativeActivity resources (#134)
The design of ndk-glue seems to imply that the user of a `NativeActivity` resource, e.g. `NativeWindow` obtained from `ndk_glue::native_window()`, should hold a read lock on the resource as long as they are using it. Therefore, ndk-glue's `NativeActivity` callbacks related to resource release should: (1) notify the user of upcoming resource release, (2) acquire a write lock on the handle, waiting for all read locks to be dropped, (3) drop the handle, (4) return from the callback. This allows the user to react and correctly release various objects derived from the resource (e.g. swapchains/surfaces from `NativeWindow`) before it goes away. Currently, the order is 2-3-1-4, which can lead to a deadlock (if the user holds on to a read guard) or a race condition (if they drop the read guard early). This commit fixes the order.
1 parent b430a5e commit ca87ad8

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

ndk-glue/src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ unsafe extern "C" fn on_window_destroyed(
278278
activity: *mut ANativeActivity,
279279
_window: *mut ANativeWindow,
280280
) {
281-
*NATIVE_WINDOW.write().unwrap() = None;
282281
wake(activity, Event::WindowDestroyed);
282+
*NATIVE_WINDOW.write().unwrap() = None;
283283
}
284284

285285
unsafe extern "C" fn on_input_queue_created(
@@ -300,10 +300,12 @@ unsafe extern "C" fn on_input_queue_destroyed(
300300
activity: *mut ANativeActivity,
301301
queue: *mut AInputQueue,
302302
) {
303+
wake(activity, Event::InputQueueDestroyed);
304+
let mut input_queue_guard = INPUT_QUEUE.write().unwrap();
305+
assert_eq!(input_queue_guard.as_ref().unwrap().ptr().as_ptr(), queue);
303306
let input_queue = InputQueue::from_ptr(NonNull::new(queue).unwrap());
304307
input_queue.detach_looper();
305-
*INPUT_QUEUE.write().unwrap() = None;
306-
wake(activity, Event::InputQueueDestroyed);
308+
*input_queue_guard = None;
307309
}
308310

309311
unsafe extern "C" fn on_content_rect_changed(activity: *mut ANativeActivity, rect: *const ARect) {

0 commit comments

Comments
 (0)