Browse Source

Merge pull request #102837 from raulsntos/dotnet/fix-reload-callables

[.NET] Skip serializing delegates with a disposed target
Rémi Verschelde 2 months ago
parent
commit
7e9b709917

+ 8 - 2
modules/mono/csharp_script.cpp

@@ -685,8 +685,14 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
 
 			if (success) {
 				ManagedCallable::instances_pending_reload.insert(managed_callable, serialized_data);
-			} else if (OS::get_singleton()->is_stdout_verbose()) {
-				OS::get_singleton()->print("Failed to serialize delegate\n");
+			} else {
+				if (OS::get_singleton()->is_stdout_verbose()) {
+					OS::get_singleton()->print("Failed to serialize delegate.\n");
+				}
+
+				// We failed to serialize the delegate but we still have to release it;
+				// otherwise, we won't be able to unload the assembly.
+				managed_callable->release_delegate_handle();
 			}
 		}
 	}

+ 6 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs

@@ -166,6 +166,12 @@ namespace Godot
                 }
                 case GodotObject godotObject:
                 {
+                    if (!GodotObject.IsInstanceValid(godotObject))
+                    {
+                        // If the delegate's target has been freed we can't serialize it.
+                        return false;
+                    }
+
                     using (var stream = new MemoryStream())
                     using (var writer = new BinaryWriter(stream))
                     {