Skip to content

Conversation

@sfod
Copy link
Contributor

@sfod sfod commented Nov 20, 2025

Issue #, if available:

The issue this PR fixes appears on Apple platforms with dispatch queue event loop enabled and using GraalVM.

Currently, when a native callback is executed, crt-java assumes it always runs on a dispatch queue thread. So, at the beginning of a callback, the thread attaches to JVM, and at the end - detaches from JVM. However, sometimes callbacks can be actually executed in the main thread, like in the bootstrap create-destroy test. This leads to callbacks attempting to detach the main JVM thread from JVM.
When executing in JVM mode, it seems such requests are simply being ignored, otherwise we should have seen errors. But in GraalVM this leads to the following error:

[TEST START] software.amazon.awssdk.crt.test.ClientBootstrapTest#testCreateDestroy
Fatal error: Must either be at a safepoint or in native mode

and then crash.

Description of changes:

This PR does for dispatch queue threads what is basically already done for CRT threads: detachment will happen only if attachment actually happened at the beginning of a callback.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@sfod sfod changed the title Use flag for threads detachment Detach only external threads Nov 20, 2025
@sfod sfod force-pushed the conditional-thread-detach branch from 46dc795 to be65f4e Compare November 20, 2025 21:27
sbSteveK
sbSteveK previously approved these changes Nov 20, 2025
@sbSteveK sbSteveK dismissed their stale review November 20, 2025 22:21

bret will ask for changes

Copy link
Contributor

@bretambrose bretambrose left a comment

Choose a reason for hiding this comment

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

As annoying as it will be to do (given how often it's used), I'd prefer to see a slight change to how this is done:

Add a aws_jvm_thread_attachment_context struct (or similar name) that contains the env and the bool, ala:

struct aws_jvm_thread_attachment_context {
   JNIEnv *env;
   bool should_detach;
};

and have aws_jni_acquire_thread_env() return the struct by value. Then the pattern becomes:

   struct aws_jvm_thread_attachment_context attachment_context = aws_jni_acquire_thread_env(jvm);
   JNIEnv *env = attachment_context.env;

   ...

   aws_jni_release(thread_env(jvm, &attachment_context);

I prefer encapsulating the attachment state in one type rather than splitting into two (and maybe more in the future?) separate fields.

@bretambrose
Copy link
Contributor

As annoying as it will be to do (given how often it's used), I'd prefer to see a slight change to how this is done:

Add a aws_jvm_thread_attachment_context struct (or similar name) that contains the env and the bool, ala:

struct aws_jvm_thread_attachment_context {
   JNIEnv *env;
   bool should_detach;
};

and have aws_jni_acquire_thread_env() return the struct by value. Then the pattern becomes:

   struct aws_jvm_thread_attachment_context attachment_context = aws_jni_acquire_thread_env(jvm);
   JNIEnv *env = attachment_context.env;

   ...

   aws_jni_release(thread_env(jvm, &attachment_context);

I prefer encapsulating the attachment state in one type rather than splitting into two (and maybe more in the future?) separate fields.

Or maybe struct aws_jvm_env or similar to make it more general along the lines of "this holds all the state we need to perform JNI calls from native.

@sfod sfod merged commit f9cb644 into main Nov 25, 2025
98 of 101 checks passed
@sfod sfod deleted the conditional-thread-detach branch November 25, 2025 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants