Skip to content

Commit

Permalink
Notify event pipe before releasing NativeActivity resources
Browse files Browse the repository at this point in the history
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 correctly
release various objects derived from the resource (e.g. `EGLSurface` from
`NativeWindow`) before it goes away.  Currently, the order is 2-3-1-4, which
can lead to a deadlock or a race condition, if the user drops the read lock at
some earlier point while continuing to use objects derived from the resource.

This commit fixes the order.
  • Loading branch information
maciejgodek committed Mar 23, 2021
1 parent 3b9c4a9 commit 0a4eba8
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions ndk-glue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ unsafe extern "C" fn on_window_destroyed(
activity: *mut ANativeActivity,
_window: *mut ANativeWindow,
) {
*NATIVE_WINDOW.write().unwrap() = None;
wake(activity, Event::WindowDestroyed);
*NATIVE_WINDOW.write().unwrap() = None;
}

unsafe extern "C" fn on_input_queue_created(
Expand All @@ -279,10 +279,12 @@ unsafe extern "C" fn on_input_queue_destroyed(
activity: *mut ANativeActivity,
queue: *mut AInputQueue,
) {
wake(activity, Event::InputQueueDestroyed);
let input_queue = InputQueue::from_ptr(NonNull::new(queue).unwrap());
let mut input_queue_lock = INPUT_QUEUE.write().unwrap();
assert!(input_queue_lock.as_ref().unwrap().ptr() == input_queue.ptr());
input_queue.detach_looper();
*INPUT_QUEUE.write().unwrap() = None;
wake(activity, Event::InputQueueDestroyed);
*input_queue_lock = None;
}

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

0 comments on commit 0a4eba8

Please sign in to comment.