diff --git a/src/native/aws_signing.c b/src/native/aws_signing.c index dac740954..9e1a2b6a7 100644 --- a/src/native/aws_signing.c +++ b/src/native/aws_signing.c @@ -205,7 +205,8 @@ static void s_aws_request_signing_complete(struct aws_signing_result *result, in struct s_aws_sign_request_callback_data *callback_data = userdata; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -235,7 +236,7 @@ done:; JavaVM *jvm = callback_data->jvm; s_cleanup_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -244,7 +245,8 @@ static void s_aws_chunk_like_signing_complete(struct aws_signing_result *result, struct s_aws_sign_request_callback_data *callback_data = userdata; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -262,7 +264,7 @@ done:; JavaVM *jvm = callback_data->jvm; s_cleanup_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -278,7 +280,8 @@ static bool s_should_sign_header(const struct aws_byte_cursor *name, void *user_ struct aws_signing_config_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return false; @@ -292,7 +295,7 @@ static bool s_should_sign_header(const struct aws_byte_cursor *name, void *user_ (*env)->DeleteLocalRef(env, header_name); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; diff --git a/src/native/client_bootstrap.c b/src/native/client_bootstrap.c index 94b689448..d88e23403 100644 --- a/src/native/client_bootstrap.c +++ b/src/native/client_bootstrap.c @@ -47,7 +47,8 @@ static void s_client_bootstrap_shutdown_complete(void *user_data) { struct shutdown_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -62,7 +63,7 @@ static void s_client_bootstrap_shutdown_complete(void *user_data) { JavaVM *jvm = callback_data->jvm; s_shutdown_callback_data_destroy(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/credentials_provider.c b/src/native/credentials_provider.c index 3320aec5f..18c936b90 100644 --- a/src/native/credentials_provider.c +++ b/src/native/credentials_provider.c @@ -70,7 +70,8 @@ static void s_on_shutdown_complete(void *user_data) { // Tell the Java credentials providers that shutdown is done. This lets it release its references. /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -89,8 +90,7 @@ static void s_on_shutdown_complete(void *user_data) { JavaVM *jvm = callback_data->jvm; s_callback_data_clean_up(env, allocator, callback_data); - - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -560,7 +560,8 @@ static int s_credentials_provider_delegate_get_credentials( int return_value = AWS_OP_ERR; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -590,7 +591,7 @@ static int s_credentials_provider_delegate_get_credentials( done: (*env)->DeleteLocalRef(env, java_credentials); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return return_value; @@ -688,14 +689,14 @@ static void s_aws_login_token_source_data_on_zero_ref(void *user_data) { JavaVM *jvm = login_token_source_data->jvm; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env != NULL) { if (login_token_source_data->login_token_source != NULL) { (*env)->DeleteGlobalRef(env, login_token_source_data->login_token_source); } } - - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ aws_mem_release(login_token_source_data->allocator, login_token_source_data); @@ -855,7 +856,8 @@ static int s_cognito_get_token_pairs( JavaVM *jvm = login_token_source_data->jvm; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { return aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_DESTROYED); } @@ -911,7 +913,7 @@ static int s_cognito_get_token_pairs( s_aws_login_token_source_invocation_destroy(invocation, env); } - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; @@ -1103,7 +1105,8 @@ static void s_on_get_credentials_callback(struct aws_credentials *credentials, i struct aws_credentials_provider_get_credentials_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -1131,8 +1134,7 @@ static void s_on_get_credentials_callback(struct aws_credentials *credentials, i JavaVM *jvm = callback_data->jvm; s_cp_callback_data_clean_up(callback_data, env); - - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/crt.c b/src/native/crt.c index c0c050497..67c74e8eb 100644 --- a/src/native/crt.c +++ b/src/native/crt.c @@ -69,21 +69,18 @@ static void s_detach_jvm_from_thread(void *user_data) { /* we don't need this JNIEnv, but this is an easy way to verify the JVM is still valid to use */ /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(jvm); - if (env != NULL) { + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + if (jvm_env_context.env != NULL) { (*jvm)->DetachCurrentThread(jvm); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } } -static JNIEnv *s_aws_jni_get_thread_env(JavaVM *jvm) { -#ifdef ANDROID - JNIEnv *env = NULL; -#else - void *env = NULL; -#endif - if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_6) == JNI_EDETACHED) { +static struct aws_jvm_env_context s_aws_jni_get_thread_env(JavaVM *jvm) { + struct aws_jvm_env_context jvm_env_context = {.env = NULL, .should_detach = false}; + + if ((*jvm)->GetEnv(jvm, (void **)&jvm_env_context.env, JNI_VERSION_1_6) == JNI_EDETACHED) { if (!s_dispatch_queue_threads) { AWS_LOGF_DEBUG(AWS_LS_COMMON_GENERAL, "s_aws_jni_get_thread_env returned detached, attaching"); } @@ -106,9 +103,9 @@ static JNIEnv *s_aws_jni_get_thread_env(JavaVM *jvm) { } #ifdef ANDROID - jint result = (*jvm)->AttachCurrentThreadAsDaemon(jvm, &env, &attach_args); + jint result = (*jvm)->AttachCurrentThreadAsDaemon(jvm, &jvm_env_context.env, &attach_args); #else - jint result = (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&env, &attach_args); + jint result = (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void **)&jvm_env_context.env, &attach_args); #endif aws_string_destroy(thread_name); @@ -117,9 +114,12 @@ static JNIEnv *s_aws_jni_get_thread_env(JavaVM *jvm) { AWS_FATAL_ASSERT(result != JNI_ENOMEM); if (result != JNI_OK) { fprintf(stderr, "Unrecoverable AttachCurrentThreadAsDaemon failed, JNI error code is %d\n", (int)result); - return NULL; + jvm_env_context.env = NULL; + return jvm_env_context; } + jvm_env_context.should_detach = true; + /* Dispatch Queue threads are managed by Apple's GCD and thus can't have an at_exit callback assigned. We manually detatch dispatch queue threads from the JVM during `aws_jni_release_thread_env()` to insure cleanup. @@ -131,7 +131,7 @@ static JNIEnv *s_aws_jni_get_thread_env(JavaVM *jvm) { } } - return env; + return jvm_env_context; } /* @@ -210,7 +210,12 @@ static void s_jvm_table_remove_jvm_for_env(JNIEnv *env) { aws_rw_lock_wunlock(&s_jvm_table_lock); } -JNIEnv *aws_jni_acquire_thread_env(JavaVM *jvm) { +struct aws_jvm_env_context aws_jni_acquire_thread_env(JavaVM *jvm) { + struct aws_jvm_env_context jvm_env_context = { + .env = NULL, + .should_detach = false, + }; + /* * We use try-lock here in order to avoid the re-entrant deadlock case that could happen if we have a read * lock already, the JVM shutdown hooks causes another thread to block on taking the write lock, and then @@ -221,7 +226,7 @@ JNIEnv *aws_jni_acquire_thread_env(JavaVM *jvm) { if (aws_last_error() != AWS_ERROR_UNSUPPORTED_OPERATION) { aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_DESTROYED); } - return NULL; + return jvm_env_context; } if (s_jvms == NULL) { @@ -236,32 +241,31 @@ JNIEnv *aws_jni_acquire_thread_env(JavaVM *jvm) { goto error; } - JNIEnv *env = s_aws_jni_get_thread_env(jvm); - if (env == NULL) { + jvm_env_context = s_aws_jni_get_thread_env(jvm); + if (jvm_env_context.env == NULL) { aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_DESTROYED); goto error; } - return env; + return jvm_env_context; error: aws_rw_lock_runlock(&s_jvm_table_lock); - return NULL; + return jvm_env_context; } -void aws_jni_release_thread_env(JavaVM *jvm, JNIEnv *env) { - (void)jvm; - (void)env; - - if (env != NULL) { +void aws_jni_release_thread_env(JavaVM *jvm, struct aws_jvm_env_context *jvm_env_context) { + if (jvm_env_context->env != NULL) { /* Dispatch Queue threads must be manually detached after they're used instead of depending on a thread exit callback due to the threads not being managed by the CRT and thus, their lifetimes not trackable outside the context of their immediate use. + An additional needs_detach variable is needed to avoid detaching JVM threads. It happens + when a callback is executed on a JVM thread. */ - if (s_dispatch_queue_threads) { + if (s_dispatch_queue_threads && jvm_env_context->should_detach) { (*jvm)->DetachCurrentThread(jvm); } diff --git a/src/native/crt.h b/src/native/crt.h index 3c5f26f1e..5b5195cfe 100644 --- a/src/native/crt.h +++ b/src/native/crt.h @@ -33,6 +33,13 @@ enum aws_java_crt_error { struct aws_allocator *aws_jni_get_allocator(void); +/* This struct holds everything needed to interact with the JVM from native functions. */ +struct aws_jvm_env_context { + JNIEnv *env; + /* Determines whether to detach non-CRT threads at the end of a callback. */ + bool should_detach; +}; + /******************************************************************************* * aws_jni_throw_runtime_exception - throws a crt.CrtRuntimeException with the * supplied message, sprintf formatted. Control WILL return from this function, @@ -227,17 +234,21 @@ struct aws_string *aws_jni_new_string_from_jstring(JNIEnv *env, jstring str); /******************************************************************************* * aws_jni_acquire_thread_env - Acquires the JNIEnv for the current thread from the VM, - * attaching the env if necessary. aws_jni_release_thread_env() must be called once + * attaching the env if necessary. aws_jni_release_thread_env() must be called once * the caller is through with the environment. + * The needs_detach field in the returned context will be set to true if the thread + * was not attached to JVM when this function was called, and false otherwise. ******************************************************************************/ -JNIEnv *aws_jni_acquire_thread_env(JavaVM *jvm); +struct aws_jvm_env_context aws_jni_acquire_thread_env(JavaVM *jvm); /******************************************************************************* - * aws_jni_release_thread_env - Releases an acquired JNIEnv for the current thread. Every successfully - * acquired JNIEnv must be released exactly once. Internally, all this does is release the reader - * lock on the set of valid JVMs. + * aws_jni_release_thread_env - Releases an acquired JNIEnv for the current thread. Every + * successfully acquired JNIEnv must be released exactly once. + * Internally, it + * - releases the reader lock on the set of valid JVMs + * - detaches the dispatch queue threads (on Apple platforms only) from JVM. ******************************************************************************/ -void aws_jni_release_thread_env(JavaVM *jvm, JNIEnv *env); +void aws_jni_release_thread_env(JavaVM *jvm, struct aws_jvm_env_context *jvm_env_context); /******************************************************************************* * aws_jni_set_dispatch_queue_threads - Sets whether the current event loop group uses dispatch queue threads diff --git a/src/native/custom_key_op_handler.c b/src/native/custom_key_op_handler.c index 63d606833..9c32932af 100644 --- a/src/native/custom_key_op_handler.c +++ b/src/native/custom_key_op_handler.c @@ -42,7 +42,8 @@ static void s_aws_custom_key_op_handler_perform_operation( AWS_ASSERT(operation != NULL); /* Get the Java ENV */ - JNIEnv *env = aws_jni_acquire_thread_env(op_handler->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(op_handler->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* JVM is likely shutting down. Do not crash but log error. */ AWS_LOGF_ERROR( @@ -105,7 +106,7 @@ static void s_aws_custom_key_op_handler_perform_operation( } /* Release the Java ENV */ - aws_jni_release_thread_env(op_handler->jvm, env); + aws_jni_release_thread_env(op_handler->jvm, &jvm_env_context); } static void s_aws_custom_key_op_handler_destroy(struct aws_custom_key_op_handler *key_op_handler) { @@ -113,7 +114,8 @@ static void s_aws_custom_key_op_handler_destroy(struct aws_custom_key_op_handler struct aws_jni_custom_key_op_handler *op_handler = (struct aws_jni_custom_key_op_handler *)key_op_handler->impl; /* Get the Java ENV */ - JNIEnv *env = aws_jni_acquire_thread_env(op_handler->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(op_handler->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* JVM is likely shutting down. Do not crash but log error. */ AWS_LOGF_ERROR( @@ -127,7 +129,7 @@ static void s_aws_custom_key_op_handler_destroy(struct aws_custom_key_op_handler } /* Release the Java ENV */ - aws_jni_release_thread_env(op_handler->jvm, env); + aws_jni_release_thread_env(op_handler->jvm, &jvm_env_context); /* Release the Java struct */ aws_mem_release(op_handler->allocator, op_handler); diff --git a/src/native/event_stream_rpc_client.c b/src/native/event_stream_rpc_client.c index cb8354eb2..ff11b125f 100644 --- a/src/native/event_stream_rpc_client.c +++ b/src/native/event_stream_rpc_client.c @@ -55,7 +55,8 @@ static void s_on_connection_setup( struct connection_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -77,7 +78,7 @@ static void s_on_connection_setup( s_destroy_connection_callback_data(callback_data, env); } - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -90,7 +91,8 @@ static void s_on_connection_shutdown( struct connection_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -106,7 +108,7 @@ static void s_on_connection_shutdown( JavaVM *jvm = callback_data->jvm; s_destroy_connection_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -119,7 +121,8 @@ static void s_connection_protocol_message( struct connection_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -144,7 +147,7 @@ static void s_connection_protocol_message( (*env)->DeleteLocalRef(env, headers_array); aws_jni_check_and_clear_exception(env); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -345,7 +348,8 @@ static void s_message_flush_fn(int error_code, void *user_data) { struct message_flush_callback_args *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -358,7 +362,7 @@ static void s_message_flush_fn(int error_code, void *user_data) { JavaVM *jvm = callback_data->jvm; s_destroy_message_flush_callback_args(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -455,7 +459,8 @@ static void s_stream_continuation( struct continuation_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -481,7 +486,7 @@ static void s_stream_continuation( /* don't really care if they threw here, but we want to make the jvm happy that we checked */ aws_jni_check_and_clear_exception(env); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -492,7 +497,8 @@ static void s_stream_continuation_closed( struct continuation_callback_data *continuation_callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(continuation_callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(continuation_callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -507,7 +513,7 @@ static void s_stream_continuation_closed( JavaVM *jvm = continuation_callback_data->jvm; s_client_continuation_data_destroy(env, continuation_callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/event_stream_rpc_server.c b/src/native/event_stream_rpc_server.c index 174c56f38..14b96ccdf 100644 --- a/src/native/event_stream_rpc_server.c +++ b/src/native/event_stream_rpc_server.c @@ -88,7 +88,8 @@ static void s_server_listener_shutdown_complete( struct shutdown_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -102,7 +103,7 @@ static void s_server_listener_shutdown_complete( JavaVM *jvm = callback_data->jvm; s_shutdown_callback_data_destroy(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -137,7 +138,8 @@ static void s_stream_continuation_fn( struct continuation_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -161,7 +163,7 @@ static void s_stream_continuation_fn( /* don't really care if they threw here, but we want to make the jvm happy that we checked */ aws_jni_check_and_clear_exception(env); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -172,7 +174,8 @@ static void s_stream_continuation_closed_fn( struct continuation_callback_data *continuation_callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(continuation_callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(continuation_callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -187,7 +190,7 @@ static void s_stream_continuation_closed_fn( JavaVM *jvm = continuation_callback_data->jvm; s_server_continuation_data_destroy(env, continuation_callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -205,7 +208,8 @@ static int s_on_incoming_stream_fn( jobject java_continuation_handler = NULL; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -270,7 +274,7 @@ static int s_on_incoming_stream_fn( (*env)->DeleteLocalRef(env, java_continuation_handler); (*env)->DeleteLocalRef(env, java_continuation); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE SUCCESS PATH **********/ return AWS_OP_SUCCESS; @@ -288,7 +292,7 @@ static int s_on_incoming_stream_fn( aws_event_stream_rpc_server_connection_close(connection, aws_last_error()); s_server_continuation_data_destroy(env, continuation_callback_data); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE FAILURE PATH **********/ return AWS_OP_ERR; @@ -303,7 +307,8 @@ static void s_connection_protocol_message_fn( struct connection_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -328,7 +333,7 @@ static void s_connection_protocol_message_fn( /* don't really care if they threw here, but we want to make the jvm happy that we checked */ aws_jni_check_and_clear_exception(env); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -341,7 +346,8 @@ static int s_on_new_connection_fn( struct shutdown_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -403,7 +409,7 @@ static int s_on_new_connection_fn( (*env)->DeleteLocalRef(env, java_connection_handler); (*env)->DeleteLocalRef(env, java_server_connection); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE SUCCESS PATH **********/ return AWS_OP_SUCCESS; @@ -420,7 +426,7 @@ static int s_on_new_connection_fn( s_server_connection_data_destroy(env, connection_callback_data); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE ERROR PATH **********/ return AWS_OP_ERR; @@ -439,7 +445,8 @@ static void s_on_connection_shutdown_fn( } /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -466,7 +473,7 @@ static void s_on_connection_shutdown_fn( /* this is the should be connection specific callback data. */ JavaVM *jvm = callback_data->jvm; s_server_connection_data_destroy(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -716,7 +723,8 @@ static void s_message_flush_fn(int error_code, void *user_data) { struct message_flush_callback_args *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -728,7 +736,7 @@ static void s_message_flush_fn(int error_code, void *user_data) { JavaVM *jvm = callback_data->jvm; s_destroy_message_flush_callback_args(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/http2_stream_manager.c b/src/native/http2_stream_manager.c index dae6cf301..90df355d2 100644 --- a/src/native/http2_stream_manager.c +++ b/src/native/http2_stream_manager.c @@ -64,7 +64,8 @@ static void s_on_stream_manager_shutdown_complete_callback(void *user_data) { struct aws_http2_stream_manager_binding *binding = (struct aws_http2_stream_manager_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -82,7 +83,7 @@ static void s_on_stream_manager_shutdown_complete_callback(void *user_data) { /* We're done with this wrapper, free it. */ JavaVM *jvm = binding->jvm; s_destroy_manager_binding(binding, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -307,7 +308,8 @@ static struct aws_sm_acquire_stream_callback_data *s_new_sm_acquire_stream_callb static void s_on_stream_acquired(struct aws_http_stream *stream, int error_code, void *user_data) { struct aws_sm_acquire_stream_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -348,7 +350,7 @@ static void s_on_stream_acquired(struct aws_http_stream *stream, int error_code, AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); JavaVM *jvm = callback_data->jvm; s_cleanup_sm_acquire_stream_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/http_connection_manager.c b/src/native/http_connection_manager.c index 3ad71566c..c53b6ce31 100644 --- a/src/native/http_connection_manager.c +++ b/src/native/http_connection_manager.c @@ -65,7 +65,8 @@ static void s_on_http_conn_manager_shutdown_complete_callback(void *user_data) { struct http_connection_manager_binding *binding = (struct http_connection_manager_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -82,8 +83,7 @@ static void s_on_http_conn_manager_shutdown_complete_callback(void *user_data) { // We're done with this wrapper, free it. JavaVM *jvm = binding->jvm; s_destroy_manager_binding(binding, env); - - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -316,7 +316,8 @@ static void s_on_http_conn_acquisition_callback( binding->connection = connection; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -347,7 +348,7 @@ static void s_on_http_conn_acquisition_callback( s_destroy_connection_binding(binding, env); } - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/http_request_response.c b/src/native/http_request_response.c index 1f56dbe44..b2f4529d0 100644 --- a/src/native/http_request_response.c +++ b/src/native/http_request_response.c @@ -159,7 +159,8 @@ int aws_java_http_stream_on_incoming_header_block_done_fn( struct http_stream_binding *binding = (struct http_stream_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -206,7 +207,7 @@ int aws_java_http_stream_on_incoming_header_block_done_fn( done: - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; @@ -221,7 +222,8 @@ int aws_java_http_stream_on_incoming_body_fn( size_t total_window_increment = 0; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -262,7 +264,7 @@ int aws_java_http_stream_on_incoming_body_fn( done: - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; @@ -272,7 +274,8 @@ void aws_java_http_stream_on_stream_complete_fn(struct aws_http_stream *stream, struct http_stream_binding *binding = (struct http_stream_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -292,7 +295,7 @@ void aws_java_http_stream_on_stream_complete_fn(struct aws_http_stream *stream, aws_http_connection_close(aws_http_stream_get_connection(stream)); } - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -300,7 +303,8 @@ void aws_java_http_stream_on_stream_destroy_fn(void *user_data) { struct http_stream_binding *binding = (struct http_stream_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -308,7 +312,7 @@ void aws_java_http_stream_on_stream_destroy_fn(void *user_data) { /* Native stream destroyed, release the binding. */ JavaVM *jvm = binding->jvm; aws_http_stream_binding_release(env, binding); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -319,7 +323,8 @@ void aws_java_http_stream_on_stream_metrics_fn( struct http_stream_binding *binding = (struct http_stream_binding *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -358,7 +363,7 @@ void aws_java_http_stream_on_stream_metrics_fn( aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE); } - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -527,7 +532,8 @@ static void s_write_chunk_complete(struct aws_http_stream *stream, int error_cod struct http_stream_chunked_callback_data *chunked_callback_data = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(chunked_callback_data->stream_cb_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(chunked_callback_data->stream_cb_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -542,7 +548,7 @@ static void s_write_chunk_complete(struct aws_http_stream *stream, int error_cod JavaVM *jvm = chunked_callback_data->stream_cb_data->jvm; s_cleanup_chunked_callback_data(env, chunked_callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -848,7 +854,8 @@ static void s_on_settings_completed(struct aws_http_connection *http2_connection /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = callback_data->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -864,7 +871,7 @@ static void s_on_settings_completed(struct aws_http_connection *http2_connection AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); s_cleanup_http2_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -935,7 +942,8 @@ static void s_on_ping_completed( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = callback_data->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -958,7 +966,7 @@ static void s_on_ping_completed( AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); s_cleanup_http2_callback_data(callback_data, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } diff --git a/src/native/http_request_utils.c b/src/native/http_request_utils.c index 483854ffd..e3274a22b 100644 --- a/src/native/http_request_utils.c +++ b/src/native/http_request_utils.c @@ -41,7 +41,8 @@ static int s_aws_input_stream_seek(struct aws_input_stream *stream, int64_t offs } /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -56,7 +57,7 @@ static int s_aws_input_stream_seek(struct aws_input_stream *stream, int64_t offs result = aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE); } - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -85,7 +86,8 @@ static int s_aws_input_stream_read(struct aws_input_stream *stream, struct aws_b } /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -108,7 +110,7 @@ static int s_aws_input_stream_read(struct aws_input_stream *stream, struct aws_b (*env)->DeleteLocalRef(env, direct_buffer); - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; @@ -132,7 +134,8 @@ static int s_aws_input_stream_get_length(struct aws_input_stream *stream, int64_ if (impl->http_request_body_stream != NULL) { /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -146,7 +149,7 @@ static int s_aws_input_stream_get_length(struct aws_input_stream *stream, int64_ result = aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE); } - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; @@ -158,7 +161,8 @@ static int s_aws_input_stream_get_length(struct aws_input_stream *stream, int64_ static void s_aws_input_stream_destroy(struct aws_http_request_body_stream_impl *impl) { /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -168,7 +172,7 @@ static void s_aws_input_stream_destroy(struct aws_http_request_body_stream_impl (*env)->DeleteGlobalRef(env, impl->http_request_body_stream); } - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ aws_mem_release(impl->allocator, impl); diff --git a/src/native/mqtt5_client.c b/src/native/mqtt5_client.c index 5100ef3b8..2d59c8b26 100644 --- a/src/native/mqtt5_client.c +++ b/src/native/mqtt5_client.c @@ -303,7 +303,8 @@ static void s_aws_mqtt5_client_java_lifecycle_event(const struct aws_mqtt5_clien /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = java_client->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "LifecycleEvent: could not get env"); @@ -357,7 +358,7 @@ static void s_aws_mqtt5_client_java_lifecycle_event(const struct aws_mqtt5_clien if (local_frame_result != 0) { s_aws_mqtt5_client_log_and_throw_exception( env, "LifecycleEvent: could not push local JNI frame with 14 allocation minimum!", AWS_ERROR_INVALID_STATE); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); return; } @@ -503,7 +504,7 @@ static void s_aws_mqtt5_client_java_lifecycle_event(const struct aws_mqtt5_clien (*env)->PopLocalFrame(env, NULL); /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } static void s_aws_mqtt5_client_java_publish_received( @@ -523,7 +524,8 @@ static void s_aws_mqtt5_client_java_publish_received( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = java_client->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "publishReceived function: could not get env"); @@ -598,7 +600,7 @@ static void s_aws_mqtt5_client_java_publish_received( (*env)->PopLocalFrame(env, NULL); /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } static void s_aws_mqtt5_client_java_publish_callback_destructor( @@ -623,6 +625,7 @@ static void s_aws_mqtt5_client_java_publish_completion( int exception_error_code = error_code; JavaVM *jvm = NULL; JNIEnv *env = NULL; + struct aws_jvm_env_context jvm_env_context; bool has_pushed_frame = false; struct aws_mqtt5_client_publish_return_data *return_data = (struct aws_mqtt5_client_publish_return_data *)user_data; @@ -639,7 +642,8 @@ static void s_aws_mqtt5_client_java_publish_completion( /********** JNI ENV ACQUIRE **********/ jvm = java_client->jvm; - env = aws_jni_acquire_thread_env(jvm); + jvm_env_context = aws_jni_acquire_thread_env(jvm); + env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "PublishCompletion function: could not get env"); @@ -739,7 +743,7 @@ static void s_aws_mqtt5_client_java_publish_completion( (*env)->PopLocalFrame(env, NULL); } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } return; } @@ -765,6 +769,7 @@ static void s_aws_mqtt5_client_java_subscribe_completion( int exception_error_code = error_code; JNIEnv *env = NULL; JavaVM *jvm = NULL; + struct aws_jvm_env_context jvm_env_context; bool has_pushed_frame = false; struct aws_mqtt5_client_subscribe_return_data *return_data = @@ -781,7 +786,8 @@ static void s_aws_mqtt5_client_java_subscribe_completion( /********** JNI ENV ACQUIRE **********/ jvm = java_client->jvm; - env = aws_jni_acquire_thread_env(jvm); + jvm_env_context = aws_jni_acquire_thread_env(jvm); + env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "SubscribeCompletion: could not get env"); @@ -893,7 +899,7 @@ static void s_aws_mqtt5_client_java_subscribe_completion( (*env)->PopLocalFrame(env, NULL); } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } } @@ -918,6 +924,7 @@ static void s_aws_mqtt5_client_java_unsubscribe_completion( int exception_error_code = error_code; JNIEnv *env = NULL; JavaVM *jvm = NULL; + struct aws_jvm_env_context jvm_env_context; bool has_pushed_frame = false; struct aws_mqtt5_client_unsubscribe_return_data *return_data = @@ -935,7 +942,8 @@ static void s_aws_mqtt5_client_java_unsubscribe_completion( /********** JNI ENV ACQUIRE **********/ jvm = java_client->jvm; - env = aws_jni_acquire_thread_env(jvm); + jvm_env_context = aws_jni_acquire_thread_env(jvm); + env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "UnsubscribeCompletion: could not get env"); @@ -1042,7 +1050,7 @@ static void s_aws_mqtt5_client_java_unsubscribe_completion( (*env)->PopLocalFrame(env, NULL); } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } } @@ -1056,7 +1064,8 @@ static void s_aws_mqtt5_client_java_termination(void *complete_ctx) { /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = java_client->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_MQTT5_CLIENT, "MQTT5 client termination function in JNI called, but could not get env"); @@ -1070,7 +1079,7 @@ static void s_aws_mqtt5_client_java_termination(void *complete_ctx) { aws_mqtt5_client_java_destroy(env, allocator, java_client); /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } /******************************************************************************* @@ -1520,7 +1529,8 @@ static void s_aws_mqtt5_client_java_websocket_handshake_transform( } /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(java_client->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(java_client->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ complete_fn(request, AWS_ERROR_INVALID_STATE, complete_ctx); @@ -1553,7 +1563,7 @@ static void s_aws_mqtt5_client_java_websocket_handshake_transform( } (*env)->DeleteLocalRef(env, java_http_request); - aws_jni_release_thread_env(java_client->jvm, env); + aws_jni_release_thread_env(java_client->jvm, &jvm_env_context); /********** JNI ENV RELEASE SUCCESS PATH **********/ return; @@ -1562,7 +1572,7 @@ error:; int error_code = aws_last_error(); s_ws_handshake_destroy(ws_handshake); complete_fn(request, error_code, complete_ctx); - aws_jni_release_thread_env(java_client->jvm, env); + aws_jni_release_thread_env(java_client->jvm, &jvm_env_context); /********** JNI ENV RELEASE FAILURE PATH **********/ } diff --git a/src/native/mqtt_connection.c b/src/native/mqtt_connection.c index 6848057c4..e13dfd4be 100644 --- a/src/native/mqtt_connection.c +++ b/src/native/mqtt_connection.c @@ -147,7 +147,8 @@ static void s_on_connection_complete( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = connection->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -161,7 +162,7 @@ static void s_on_connection_complete( error_code, session_present); if (aws_jni_check_and_clear_exception(env)) { - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE EARLY OUT **********/ aws_mqtt_client_connection_disconnect(client_connection, s_on_connection_disconnected, connect_callback); return; /* callback and ref count will be cleaned up in s_on_connection_disconnected */ @@ -170,7 +171,7 @@ static void s_on_connection_complete( s_mqtt_jni_async_callback_destroy(connect_callback, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ s_mqtt_jni_connection_release(connection); } @@ -203,7 +204,8 @@ static void s_on_connection_interrupted( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -211,7 +213,7 @@ static void s_on_connection_interrupted( s_on_connection_interrupted_internal(user_data, error_code, NULL, env); - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -226,7 +228,8 @@ static void s_on_connection_success( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -236,7 +239,7 @@ static void s_on_connection_success( env, connection->java_mqtt_connection, mqtt_connection_properties.on_connection_success, session_present); AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); } - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -249,7 +252,8 @@ static void s_on_connection_failure( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -259,7 +263,7 @@ static void s_on_connection_failure( env, connection->java_mqtt_connection, mqtt_connection_properties.on_connection_failure, error_code); AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); } - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -274,7 +278,8 @@ static void s_on_connection_resumed( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -286,7 +291,7 @@ static void s_on_connection_resumed( AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); } - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -297,7 +302,8 @@ static void s_on_connection_disconnected(struct aws_mqtt_client_connection *clie struct mqtt_jni_connection *jni_connection = connect_callback->connection; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(jni_connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jni_connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -309,7 +315,7 @@ static void s_on_connection_disconnected(struct aws_mqtt_client_connection *clie AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); - aws_jni_release_thread_env(jni_connection->jvm, env); + aws_jni_release_thread_env(jni_connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ /* Do not call release here: s_on_connection_closed will (normally) be called @@ -326,7 +332,8 @@ static void s_on_connection_closed( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -337,7 +344,7 @@ static void s_on_connection_closed( (*env)->CallVoidMethod(env, connection->java_mqtt_connection, mqtt_connection_properties.on_connection_closed); AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); } - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -346,7 +353,8 @@ static void s_on_connection_terminated(void *user_data) { struct mqtt_jni_connection *jni_connection = (struct mqtt_jni_connection *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(jni_connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jni_connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -360,7 +368,7 @@ static void s_on_connection_terminated(void *user_data) { JavaVM *jvm = jni_connection->jvm; s_mqtt_connection_destroy(env, jni_connection); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -698,7 +706,8 @@ static void s_on_op_complete( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = callback->connection->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { return; } @@ -711,7 +720,7 @@ static void s_on_op_complete( s_mqtt_jni_async_callback_destroy(callback, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -743,14 +752,15 @@ static void s_cleanup_handler(void *user_data) { /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = handler->connection->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { return; } s_mqtt_jni_async_callback_destroy(handler, env); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -774,7 +784,8 @@ static void s_on_subscription_delivered( } /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback->connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback->connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -793,7 +804,7 @@ static void s_on_subscription_delivered( AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); - aws_jni_release_thread_env(callback->connection->jvm, env); + aws_jni_release_thread_env(callback->connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -1143,7 +1154,8 @@ static void s_ws_handshake_transform( struct mqtt_jni_connection *connection = user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(connection->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(connection->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ complete_fn(request, AWS_ERROR_INVALID_STATE, complete_ctx); @@ -1181,7 +1193,7 @@ static void s_ws_handshake_transform( } (*env)->DeleteLocalRef(env, java_http_request); - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE SUCCESS PATH **********/ return; @@ -1191,7 +1203,7 @@ error:; int error_code = aws_last_error(); s_ws_handshake_destroy(ws_handshake); complete_fn(request, error_code, complete_ctx); - aws_jni_release_thread_env(connection->jvm, env); + aws_jni_release_thread_env(connection->jvm, &jvm_env_context); /********** JNI ENV RELEASE FAILURE PATH **********/ } diff --git a/src/native/mqtt_request_response.c b/src/native/mqtt_request_response.c index 102744b06..411f6b56b 100644 --- a/src/native/mqtt_request_response.c +++ b/src/native/mqtt_request_response.c @@ -41,7 +41,8 @@ static void s_destroy_mqtt_request_response_client_binding(void *context) { /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = binding->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_JAVA_CRT_GENERAL, "JNI env no longer resolvable; JVM likely shutting down"); @@ -53,7 +54,7 @@ static void s_destroy_mqtt_request_response_client_binding(void *context) { } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); done: @@ -226,13 +227,14 @@ static void s_aws_request_response_operation_binding_destroy(struct aws_request_ return; } - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (env && binding->operation_future) { (*env)->DeleteGlobalRef(env, binding->operation_future); } - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); aws_mem_release(binding->allocator, binding); } @@ -430,7 +432,8 @@ static void s_on_request_response_operation_completion( jstring java_topic = NULL; jbyteArray java_payload = NULL; struct aws_request_response_operation_binding *binding = user_data; - JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(binding->jvm); + JNIEnv *env = jvm_env_context.env; if (!env) { goto done; } @@ -480,7 +483,7 @@ static void s_on_request_response_operation_completion( (*env)->DeleteLocalRef(env, java_payload); } - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); s_aws_request_response_operation_binding_destroy(binding); } @@ -595,7 +598,8 @@ static void s_aws_streaming_operation_binding_destroy(struct aws_streaming_opera /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = binding->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_JAVA_CRT_GENERAL, "JNI env no longer resolvable; JVM likely shutting down"); @@ -610,7 +614,7 @@ static void s_aws_streaming_operation_binding_destroy(struct aws_streaming_opera (*env)->DeleteGlobalRef(env, binding->java_subscription_status_event_callback); } - aws_jni_release_thread_env(binding->jvm, env); + aws_jni_release_thread_env(binding->jvm, &jvm_env_context); done: @@ -629,7 +633,8 @@ static void s_aws_mqtt_streaming_operation_subscription_status_callback( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = binding->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_JAVA_CRT_GENERAL, "JNI env no longer resolvable; JVM likely shutting down"); @@ -685,7 +690,7 @@ static void s_aws_mqtt_streaming_operation_subscription_status_callback( } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } static void s_aws_mqtt_streaming_operation_incoming_publish_callback( @@ -699,7 +704,8 @@ static void s_aws_mqtt_streaming_operation_incoming_publish_callback( /********** JNI ENV ACQUIRE **********/ JavaVM *jvm = binding->jvm; - JNIEnv *env = aws_jni_acquire_thread_env(jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ AWS_LOGF_ERROR(AWS_LS_JAVA_CRT_GENERAL, "JNI env no longer resolvable; JVM likely shutting down"); @@ -781,7 +787,7 @@ static void s_aws_mqtt_streaming_operation_incoming_publish_callback( } /********** JNI ENV RELEASE **********/ - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); } static void s_aws_mqtt_streaming_operation_terminated_callback(void *user_data) { diff --git a/src/native/s3_client.c b/src/native/s3_client.c index ed4aba252..3228b1bdb 100644 --- a/src/native/s3_client.c +++ b/src/native/s3_client.c @@ -147,7 +147,8 @@ static int s_s3express_get_creds_java( int result = AWS_OP_ERR; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (!env) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_SUCCESS; @@ -214,7 +215,7 @@ static int s_s3express_get_creds_java( if (original_credentials_object) { (*env)->DeleteLocalRef(env, original_credentials_object); } - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return result; } @@ -223,7 +224,8 @@ static void s_s3express_destroy_java(struct aws_s3express_credentials_provider * struct s3_client_s3express_provider_java_impl *impl = provider->impl; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(impl->jvm); + JNIEnv *env = jvm_env_context.env; if (!env) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -234,7 +236,7 @@ static void s_s3express_destroy_java(struct aws_s3express_credentials_provider * (*env)->DeleteGlobalRef(env, impl->java_s3express_provider); - aws_jni_release_thread_env(impl->jvm, env); + aws_jni_release_thread_env(impl->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ /* Once the java call returns, the java resource should be cleaned up already. We can finish up the shutdown * process. Clean up the native part. */ @@ -263,7 +265,8 @@ struct aws_s3express_credentials_provider *s_s3express_provider_jni_factory( struct s3_client_s3express_provider_java_impl *impl = NULL; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(client_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(client_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return NULL; @@ -308,7 +311,7 @@ struct aws_s3express_credentials_provider *s_s3express_provider_jni_factory( client_data->java_s3express_provider_factory = NULL; done: - aws_jni_release_thread_env(client_data->jvm, env); + aws_jni_release_thread_env(client_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return provider; } @@ -563,7 +566,8 @@ static void s_on_s3_client_shutdown_complete_callback(void *user_data) { struct s3_client_callback_data *callback = (struct s3_client_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -591,7 +595,7 @@ static void s_on_s3_client_shutdown_complete_callback(void *user_data) { aws_signing_config_data_clean_up(&callback->signing_config_data, env); - aws_jni_release_thread_env(callback->jvm, env); + aws_jni_release_thread_env(callback->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ aws_mem_release(aws_jni_get_allocator(), user_data); @@ -612,7 +616,8 @@ static int s_on_s3_meta_request_body_callback( (struct s3_client_make_meta_request_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -622,7 +627,7 @@ static int s_on_s3_meta_request_body_callback( if (jni_payload == NULL) { /* JVM is out of memory, but native code can still have memory available, handle it and don't crash. */ aws_jni_check_and_clear_exception(env); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_OUT_OF_MEMORY); } @@ -657,7 +662,7 @@ static int s_on_s3_meta_request_body_callback( cleanup: (*env)->DeleteLocalRef(env, jni_payload); - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return return_value; @@ -697,7 +702,8 @@ static int s_on_s3_meta_request_headers_callback( (struct s3_client_make_meta_request_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; @@ -744,7 +750,7 @@ static int s_on_s3_meta_request_headers_callback( (*env)->DeleteLocalRef(env, java_headers_buffer); } - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ return return_value; @@ -761,7 +767,8 @@ static void s_on_s3_meta_request_finish_callback( (struct s3_client_make_meta_request_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -850,7 +857,7 @@ static void s_on_s3_meta_request_finish_callback( } } - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -865,7 +872,8 @@ static void s_on_s3_meta_request_progress_callback( (struct s3_client_make_meta_request_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -909,7 +917,7 @@ static void s_on_s3_meta_request_progress_callback( done: - aws_jni_release_thread_env(callback_data->jvm, env); + aws_jni_release_thread_env(callback_data->jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ } @@ -1179,7 +1187,8 @@ static void s_on_s3_meta_request_shutdown_complete_callback(void *user_data) { (struct s3_client_make_meta_request_callback_data *)user_data; /********** JNI ENV ACQUIRE **********/ - JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); + struct aws_jvm_env_context jvm_env_context = aws_jni_acquire_thread_env(callback_data->jvm); + JNIEnv *env = jvm_env_context.env; if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; @@ -1200,7 +1209,7 @@ static void s_on_s3_meta_request_shutdown_complete_callback(void *user_data) { JavaVM *jvm = callback_data->jvm; s_s3_meta_request_callback_cleanup(env, callback_data); - aws_jni_release_thread_env(jvm, env); + aws_jni_release_thread_env(jvm, &jvm_env_context); /********** JNI ENV RELEASE **********/ }