summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2021-12-28 23:25:16 +0100
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:36:51 +0200
commitf88d8902cfc0d6a9441e794eb47611ef4ed0d46c (patch)
tree98dc44db6bc821c1aa9785229e5d9f58e6b5967a /modules/mono/mono_gd
parent4d710bf659c0bea5b8f3d6ec65eda047bada0e02 (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.cpp23
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp1
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h2
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;