diff options
author | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2021-12-28 23:25:16 +0100 |
---|---|---|
committer | Ignacio Roldán Etcheverry <ignalfonsore@gmail.com> | 2022-08-22 03:36:51 +0200 |
commit | f88d8902cfc0d6a9441e794eb47611ef4ed0d46c (patch) | |
tree | 98dc44db6bc821c1aa9785229e5d9f58e6b5967a /modules/mono/mono_gd | |
parent | 4d710bf659c0bea5b8f3d6ec65eda047bada0e02 (diff) |
C#: Ensure native handles are freed after switch to .NET Core
Finalizers are longer guaranteed to be called on exit now that
we switched to .NET Core. This results in native instances leaking.
The only solution I can think of so far is to keep a list of all
instances alive to dispose when the AssemblyLoadContext.Unloading
event is raised.
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 23 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 1 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 2 |
3 files changed, 10 insertions, 16 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index dcda799f32..7a3fd1af10 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -471,26 +471,17 @@ GDMono::GDMono() { } GDMono::~GDMono() { + finalizing_scripts_domain = true; + if (is_runtime_initialized()) { -#warning "TODO assembly unloading for cleanup of disposables (including managed RefCounteds)" -#if 0 - if (scripts_domain) { - Error err = _unload_scripts_domain(); - if (err != OK) { - ERR_PRINT("Mono: Failed to unload scripts domain."); - } + if (GDMonoCache::godot_api_cache_updated) { + GDMonoCache::managed_callbacks.DisposablesTracker_OnGodotShuttingDown(); } - - print_verbose("Mono: Runtime cleanup..."); - - mono_jit_cleanup(root_domain); - - print_verbose("Mono: Finalized"); -#endif - - runtime_initialized = false; } + finalizing_scripts_domain = false; + runtime_initialized = false; + #if defined(ANDROID_ENABLED) gdmono::android::support::cleanup(); #endif diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 17addfb49d..e8b25cb119 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -68,6 +68,7 @@ void update_godot_api_cache(const ManagedCallbacks &p_managed_callbacks) { CHECK_CALLBACK_NOT_NULL(GCHandleBridge, FreeGCHandle); CHECK_CALLBACK_NOT_NULL(DebuggingUtils, InstallTraceListener); CHECK_CALLBACK_NOT_NULL(Dispatcher, InitializeDefaultGodotTaskScheduler); + CHECK_CALLBACK_NOT_NULL(DisposablesTracker, OnGodotShuttingDown); managed_callbacks = p_managed_callbacks; diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 56bf4cef94..17c8c9fa51 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -78,6 +78,7 @@ struct ManagedCallbacks { using FuncGCHandleBridge_FreeGCHandle = void(GD_CLR_STDCALL *)(GCHandleIntPtr); using FuncDebuggingUtils_InstallTraceListener = void(GD_CLR_STDCALL *)(); using FuncDispatcher_InitializeDefaultGodotTaskScheduler = void(GD_CLR_STDCALL *)(); + using FuncDisposablesTracker_OnGodotShuttingDown = void(GD_CLR_STDCALL *)(); FuncSignalAwaiter_SignalCallback SignalAwaiter_SignalCallback; FuncDelegateUtils_InvokeWithVariantArgs DelegateUtils_InvokeWithVariantArgs; @@ -104,6 +105,7 @@ struct ManagedCallbacks { FuncGCHandleBridge_FreeGCHandle GCHandleBridge_FreeGCHandle; FuncDebuggingUtils_InstallTraceListener DebuggingUtils_InstallTraceListener; FuncDispatcher_InitializeDefaultGodotTaskScheduler Dispatcher_InitializeDefaultGodotTaskScheduler; + FuncDisposablesTracker_OnGodotShuttingDown DisposablesTracker_OnGodotShuttingDown; }; extern ManagedCallbacks managed_callbacks; |