diff options
-rw-r--r-- | modules/mono/csharp_script.cpp | 11 | ||||
-rw-r--r-- | modules/mono/mono_gc_handle.cpp | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.h | 4 |
4 files changed, 22 insertions, 3 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 86e4be1882..161e130a07 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -122,6 +122,9 @@ void CSharpLanguage::init() { void CSharpLanguage::finish() { + // Release gchandle bindings before finalizing mono runtime + gchandle_bindings.clear(); + if (gdmono) { memdelete(gdmono); gdmono = NULL; @@ -827,6 +830,14 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) { void CSharpLanguage::free_instance_binding_data(void *p_data) { + if (GDMono::get_singleton() == NULL) { +#ifdef DEBUG_ENABLED + CRASH_COND(!gchandle_bindings.empty()); +#endif + // Mono runtime finalized, all the gchandle bindings were already released + return; + } + #ifndef NO_THREADS script_bind_lock->lock(); #endif diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp index d3ad968135..e10e06df0e 100644 --- a/modules/mono/mono_gc_handle.cpp +++ b/modules/mono/mono_gc_handle.cpp @@ -59,6 +59,10 @@ Ref<MonoGCHandle> MonoGCHandle::create_weak(MonoObject *p_object) { void MonoGCHandle::release() { +#ifdef DEBUG_ENABLED + CRASH_COND(GDMono::get_singleton() == NULL); +#endif + if (!released && GDMono::get_singleton()->is_runtime_initialized()) { mono_gchandle_free(handle); released = true; diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 904a8ae2c7..c997b0f000 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -705,7 +705,7 @@ bool _GodotSharp::is_domain_loaded() { void _GodotSharp::queue_dispose(Object *p_object) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { _dispose_object(p_object); } else { #ifndef NO_THREADS @@ -722,7 +722,7 @@ void _GodotSharp::queue_dispose(Object *p_object) { void _GodotSharp::queue_dispose(NodePath *p_node_path) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { memdelete(p_node_path); } else { #ifndef NO_THREADS @@ -739,7 +739,7 @@ void _GodotSharp::queue_dispose(NodePath *p_node_path) { void _GodotSharp::queue_dispose(RID *p_rid) { - if (Thread::get_main_id() == Thread::get_caller_id() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { + if (GDMonoUtils::is_main_thread() && !GDMono::get_singleton()->is_finalizing_scripts_domain()) { memdelete(p_rid); } else { #ifndef NO_THREADS diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index e3af57e78a..ebb5d28e4d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -149,6 +149,10 @@ void attach_current_thread(); void detach_current_thread(); MonoThread *get_current_thread(); +_FORCE_INLINE_ bool is_main_thread() { + return mono_domain_get() != NULL && mono_thread_get_main() == mono_thread_current(); +} + GDMonoClass *get_object_class(MonoObject *p_object); GDMonoClass *type_get_proxy_class(const StringName &p_type); GDMonoClass *get_class_native_base(GDMonoClass *p_class); |