From ebb8c435663ea7bf3bda8f1fd04869bd8ba1fef0 Mon Sep 17 00:00:00 2001 From: UnityAlex Date: Tue, 18 Dec 2018 15:38:08 -0500 Subject: [PATCH] Added ability to continue domain unload when an exception is encountered --- mono/metadata/appdomain.c | 23 +++++++++++++++-------- mono/metadata/appdomain.h | 3 ++- mono/metadata/unity-utils.c | 7 +++++++ mono/metadata/unity-utils.h | 1 + 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index db8304213e6..c9e3a5365f6 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -2277,7 +2277,7 @@ ves_icall_System_AppDomain_InternalUnload (gint32 domain_id, MonoError *error) return; MonoException *exc = NULL; - mono_domain_try_unload (domain, (MonoObject**)&exc); + mono_domain_try_unload (domain, (MonoObject**)&exc, NULL); if (exc) mono_error_set_exception_instance (error, exc); } @@ -2643,7 +2643,7 @@ void mono_domain_unload (MonoDomain *domain) { MonoObject *exc = NULL; - mono_domain_try_unload (domain, &exc); + mono_domain_try_unload (domain, &exc, NULL); } static MonoThreadInfoWaitRet @@ -2659,9 +2659,12 @@ guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertab } /** - * mono_domain_unload: + * mono_domain_try_unload: * \param domain The domain to unload * \param exc Exception information + * \param callback Passes exception information back to caller before domain is unloaded + * + * NOTE: If the callback param is not null the domain unload will continue after executing the callback. * * Unloads an appdomain. Follows the process outlined in: * http://blogs.gotdotnet.com/cbrumme @@ -2678,7 +2681,7 @@ guarded_wait (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertab * process could end up trying to abort the current thread. */ void -mono_domain_try_unload (MonoDomain *domain, MonoObject **exc) +mono_domain_try_unload (MonoDomain *domain, MonoObject **exc, MonoUnityExceptionFunc callback) { MonoError error; MonoThreadHandle *thread_handle; @@ -2724,10 +2727,14 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc) } if (*exc) { - /* Roll back the state change */ - domain->state = MONO_APPDOMAIN_CREATED; - mono_domain_set (caller_domain, FALSE); - return; + if (callback != NULL) + callback (*exc); + else { + /* Roll back the state change */ + domain->state = MONO_APPDOMAIN_CREATED; + mono_domain_set (caller_domain, FALSE); + return; + } } mono_domain_set (caller_domain, FALSE); diff --git a/mono/metadata/appdomain.h b/mono/metadata/appdomain.h index 6885044693a..3465d157f33 100644 --- a/mono/metadata/appdomain.h +++ b/mono/metadata/appdomain.h @@ -27,6 +27,7 @@ typedef struct _MonoJitInfo MonoJitInfo; typedef void (*MonoDomainFunc) (MonoDomain *domain, void* user_data); typedef void (*MonoDomainAssemblyFunc) (MonoAssembly *assembly, void* user_data); +typedef void (*MonoUnityExceptionFunc) (MonoObject* exc); MONO_API MonoDomain* mono_init (const char *filename); @@ -97,7 +98,7 @@ MONO_API void mono_domain_unload (MonoDomain *domain); MONO_API void -mono_domain_try_unload (MonoDomain *domain, MonoObject **exc); +mono_domain_try_unload (MonoDomain *domain, MonoObject **exc, MonoUnityExceptionFunc callback); MONO_API mono_bool mono_domain_is_unloading (MonoDomain *domain); diff --git a/mono/metadata/unity-utils.c b/mono/metadata/unity-utils.c index e35255672bb..6d4a47616e3 100644 --- a/mono/metadata/unity-utils.c +++ b/mono/metadata/unity-utils.c @@ -736,6 +736,13 @@ void mono_unity_domain_install_capture_context_method(MonoDomain* domain, gpoint domain->capture_context_method = callback; } + +void mono_unity_domain_unload (MonoDomain* domain, MonoUnityExceptionFunc callback) +{ + MonoObject *exc = NULL; + mono_domain_try_unload (domain, &exc, callback); +} + //array int mono_unity_array_get_element_size(MonoArray *arr) diff --git a/mono/metadata/unity-utils.h b/mono/metadata/unity-utils.h index c476a5ef92d..c8bf5f85957 100644 --- a/mono/metadata/unity-utils.h +++ b/mono/metadata/unity-utils.h @@ -102,6 +102,7 @@ guint32 mono_unity_method_get_token(MonoMethod *method); void mono_unity_domain_install_finalize_runtime_invoke(MonoDomain* domain, RuntimeInvokeFunction callback); void mono_unity_domain_install_capture_context_runtime_invoke(MonoDomain* domain, RuntimeInvokeFunction callback); void mono_unity_domain_install_capture_context_method(MonoDomain* domain, void* callback); +MONO_API void mono_unity_domain_unload (MonoDomain *domain, MonoUnityExceptionFunc callback); //array int mono_unity_array_get_element_size(MonoArray *arr); -- GitLab