Skip to content

Thread detach hook for Java JNI on Android #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
10 changes: 10 additions & 0 deletions dispatch/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,16 @@ dispatch_assert_queue_not(dispatch_queue_t queue)
#define dispatch_assert_queue_not_debug(q) dispatch_assert_queue_not(q)
#endif

/*!
* @handler dispatch_thread_detach_handler
*
* Hook to be able to detach threads before they exit from the Java JVM.
* If JNI has been used on a thread on Android it needs to have been
* "detached" before the thread exits or the application will crash.
*/
DISPATCH_EXPORT
void (*dispatch_thread_detach_handler)();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. this should go to queue_internal.h
  2. this should be (void)
  3. this should only be enabled on android

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes made. queue_interal.h doesn’t seem to be visible from Swift so I have left it where it is and prefixed the symbol with an “_" for now.


__END_DECLS

DISPATCH_ASSUME_NONNULL_END
Expand Down
4 changes: 4 additions & 0 deletions src/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,8 @@ gettid(void)
if ((f) && tsd->k) ((void(*)(void*))(f))(tsd->k); \
} while (0)

void (*dispatch_thread_detach_handler)();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be on android only


void
_libdispatch_tsd_cleanup(void *ctx)
{
Expand All @@ -885,6 +887,8 @@ _libdispatch_tsd_cleanup(void *ctx)
_tsd_call_cleanup(dispatch_voucher_key, _voucher_thread_cleanup);
_tsd_call_cleanup(dispatch_deferred_items_key,
_dispatch_deferred_items_cleanup);
if (dispatch_thread_detach_handler)
dispatch_thread_detach_handler();
tsd->tid = 0;
}

Expand Down
11 changes: 11 additions & 0 deletions src/swift/Queue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,17 @@ public extension DispatchQueue {
let p = Unmanaged.passRetained(v).toOpaque()
dispatch_queue_set_specific(self.__wrapped, k, p, _destructDispatchSpecificValue)
}

#if os(Android)
public static var threadCleanupCallback: @convention(c) () -> Void {
get {
return dispatch_thread_detach_handler
}
set(newValue) {
dispatch_thread_detach_handler = newValue
}
}
#endif
}

private func _destructDispatchSpecificValue(ptr: UnsafeMutableRawPointer?) {
Expand Down