diff --git a/src/monodroid/jni/embedded-assemblies.cc b/src/monodroid/jni/embedded-assemblies.cc index 35922e8ab85..f649c72a08c 100644 --- a/src/monodroid/jni/embedded-assemblies.cc +++ b/src/monodroid/jni/embedded-assemblies.cc @@ -494,7 +494,7 @@ EmbeddedAssemblies::typemap_java_to_managed (const char *java_type_name) return nullptr; } - MonoReflectionType *ret = mono_type_get_object (mono_domain_get (), type); + MonoReflectionType *ret = mono_type_get_object (utils.get_current_domain (), type); if (XA_UNLIKELY (ret == nullptr)) { log_warn (LOG_ASSEMBLY, "typemap: unable to instantiate managed type '%s'", managed_type_name); return nullptr; @@ -552,7 +552,7 @@ EmbeddedAssemblies::typemap_java_to_managed (const char *java_type_name) // calls `mono_get_root_domain`. Thus, we can save on a one function call here by passing `nullptr` constexpr MonoDomain *domain = nullptr; #else - MonoDomain *domain = mono_domain_get (); + MonoDomain *domain = utils.get_current_domain (); #endif MonoReflectionType *ret = mono_type_get_object (domain, mono_class_get_type (klass)); if (ret == nullptr) { diff --git a/src/monodroid/jni/monodroid-glue.cc b/src/monodroid/jni/monodroid-glue.cc index 47b9c507de6..cfcc43c5533 100644 --- a/src/monodroid/jni/monodroid-glue.cc +++ b/src/monodroid/jni/monodroid-glue.cc @@ -1741,14 +1741,16 @@ MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) log_debug (LOG_ASSEMBLY, "Dynamically opened assembly %s", mono_assembly_name_get_name (aname)); } else #endif - if (domain != mono_domain_get ()) { - MonoDomain *current = mono_domain_get (); + { + MonoDomain *current = utils.get_current_domain (); + if (domain != current) { mono_domain_set (domain, FALSE); mono_assembly_load_full (aname, NULL, NULL, 0); mono_domain_set (current, FALSE); } else { mono_assembly_load_full (aname, NULL, NULL, 0); } + } mono_assembly_name_free (aname); @@ -2327,7 +2329,7 @@ MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring manag MonoMethod *register_jni_natives = registerType; #if !defined (NET6) - MonoDomain *domain = mono_domain_get (); + MonoDomain *domain = utils.get_current_domain (/* attach_thread_if_needed */ false); mono_jit_thread_attach (domain); // Refresh current domain as it might have been modified by the above call domain = mono_domain_get (); @@ -2405,7 +2407,7 @@ JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[may #if defined (NET6) monodroidRuntime.propagate_uncaught_exception (env, javaThread, javaException); #else // def NET6 - MonoDomain *domain = mono_domain_get (); + MonoDomain *domain = utils.get_current_domain (); monodroidRuntime.propagate_uncaught_exception (domain, env, javaThread, javaException); #endif // ndef NET6 } diff --git a/src/monodroid/jni/osbridge.cc b/src/monodroid/jni/osbridge.cc index 6189e2ed961..16a9792d0c4 100644 --- a/src/monodroid/jni/osbridge.cc +++ b/src/monodroid/jni/osbridge.cc @@ -1041,7 +1041,7 @@ OSBridge::ensure_jnienv (void) JNIEnv *env; jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); if (env == nullptr) { - mono_thread_attach (mono_domain_get ()); + mono_thread_attach (utils.get_current_domain (/* attach_thread_if_needed */ false)); jvm->GetEnv ((void**)&env, JNI_VERSION_1_6); } return env; diff --git a/src/monodroid/jni/timezones.cc b/src/monodroid/jni/timezones.cc index 3a711f40f43..4d04351e20a 100644 --- a/src/monodroid/jni/timezones.cc +++ b/src/monodroid/jni/timezones.cc @@ -33,7 +33,7 @@ init () if (AndroidEnvironment_NotifyTimeZoneChanged) return; - Mono_Android_dll = utils.monodroid_load_assembly (mono_domain_get (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); + Mono_Android_dll = utils.monodroid_load_assembly (utils.get_current_domain (), SharedConstants::MONO_ANDROID_ASSEMBLY_NAME); Mono_Android_image = mono_assembly_get_image (Mono_Android_dll); AndroidEnvironment = mono_class_from_name (Mono_Android_image, SharedConstants::ANDROID_RUNTIME_NS_NAME, SharedConstants::ANDROID_ENVIRONMENT_CLASS_NAME); AndroidEnvironment_NotifyTimeZoneChanged = mono_class_get_method_from_name (AndroidEnvironment, "NotifyTimeZoneChanged", 0); diff --git a/src/monodroid/jni/util.cc b/src/monodroid/jni/util.cc index bcee4cd6f6d..25c0808a3d1 100644 --- a/src/monodroid/jni/util.cc +++ b/src/monodroid/jni/util.cc @@ -210,7 +210,7 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) MonoImageOpenStatus status; aname = mono_assembly_name_new (basename); - MonoDomain *current = mono_domain_get (); + MonoDomain *current = get_current_domain (); if (domain != current) { mono_domain_set (domain, FALSE); @@ -233,7 +233,7 @@ Util::monodroid_load_assembly (MonoDomain *domain, const char *basename) MonoObject * Util::monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *obj, void **params, MonoObject **exc) { - MonoDomain *current = mono_domain_get (); + MonoDomain *current = get_current_domain (); if (domain == current) { return mono_runtime_invoke (method, obj, params, exc); } @@ -247,7 +247,7 @@ Util::monodroid_runtime_invoke (MonoDomain *domain, MonoMethod *method, void *ob void Util::monodroid_property_set (MonoDomain *domain, MonoProperty *property, void *obj, void **params, MonoObject **exc) { - MonoDomain *current = mono_domain_get (); + MonoDomain *current = get_current_domain (); if (domain == current) { mono_property_set_value (property, obj, params, exc); return; @@ -289,7 +289,7 @@ MonoClass* Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const char* assembly, const char *_namespace, const char *type) { #if !defined (NET6) - MonoDomain *current = mono_domain_get (); + MonoDomain *current = get_current_domain (); if (domain != current) mono_domain_set (domain, FALSE); @@ -318,7 +318,7 @@ Util::monodroid_get_class_from_name ([[maybe_unused]] MonoDomain *domain, const MonoClass* Util::monodroid_get_class_from_image (MonoDomain *domain, MonoImage *image, const char *_namespace, const char *type) { - MonoDomain *current = mono_domain_get (); + MonoDomain *current = get_current_domain (); if (domain != current) mono_domain_set (domain, FALSE); diff --git a/src/monodroid/jni/util.hh b/src/monodroid/jni/util.hh index 7f2e8e67bbe..f5055862aa9 100644 --- a/src/monodroid/jni/util.hh +++ b/src/monodroid/jni/util.hh @@ -32,6 +32,7 @@ constexpr int FALSE = 0; #include #include #include +#include #include "monodroid.h" #include "jni-wrappers.hh" @@ -110,6 +111,24 @@ namespace xamarin::android return (log_categories & category) != 0; } + MonoDomain *get_current_domain (bool attach_thread_if_needed = true) const noexcept + { + MonoDomain *ret = mono_domain_get (); + if (ret != nullptr) { + return ret; + } + + // It's likely that we got a nullptr because the current thread isn't attached (see + // https://github.com/xamarin/xamarin-android/issues/6211), so we need to attach the thread to the root + // domain + ret = mono_get_root_domain (); + if (attach_thread_if_needed) { + mono_thread_attach (ret); + } + + return ret; + } + private: //char *monodroid_strdup_printf (const char *format, va_list vargs); #if !defined (NET6)