summaryrefslogtreecommitdiffstats
path: root/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/glue/GodotSharp/GodotPlugins/Main.cs')
-rw-r--r--modules/mono/glue/GodotSharp/GodotPlugins/Main.cs44
1 files changed, 25 insertions, 19 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
index 2a72b7c53e..6117ae17ea 100644
--- a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
+++ b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
@@ -21,6 +21,13 @@ namespace GodotPlugins
private sealed class PluginLoadContextWrapper
{
private PluginLoadContext? _pluginLoadContext;
+ private readonly WeakReference _weakReference;
+
+ private PluginLoadContextWrapper(PluginLoadContext pluginLoadContext, WeakReference weakReference)
+ {
+ _pluginLoadContext = pluginLoadContext;
+ _weakReference = weakReference;
+ }
public string? AssemblyLoadedPath
{
@@ -31,7 +38,14 @@ namespace GodotPlugins
public bool IsCollectible
{
[MethodImpl(MethodImplOptions.NoInlining)]
- get => _pluginLoadContext?.IsCollectible ?? false;
+ // if _pluginLoadContext is null we already started unloading, so it was collectible
+ get => _pluginLoadContext?.IsCollectible ?? true;
+ }
+
+ public bool IsAlive
+ {
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ get => _weakReference.IsAlive;
}
[MethodImpl(MethodImplOptions.NoInlining)]
@@ -43,20 +57,14 @@ namespace GodotPlugins
bool isCollectible
)
{
- var wrapper = new PluginLoadContextWrapper();
- wrapper._pluginLoadContext = new PluginLoadContext(
- pluginPath, sharedAssemblies, mainLoadContext, isCollectible);
- var assembly = wrapper._pluginLoadContext.LoadFromAssemblyName(assemblyName);
+ var context = new PluginLoadContext(pluginPath, sharedAssemblies, mainLoadContext, isCollectible);
+ var reference = new WeakReference(context, trackResurrection: true);
+ var wrapper = new PluginLoadContextWrapper(context, reference);
+ var assembly = context.LoadFromAssemblyName(assemblyName);
return (assembly, wrapper);
}
[MethodImpl(MethodImplOptions.NoInlining)]
- public WeakReference CreateWeakReference()
- {
- return new WeakReference(_pluginLoadContext, trackResurrection: true);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
internal void Unload()
{
_pluginLoadContext?.Unload();
@@ -165,7 +173,7 @@ namespace GodotPlugins
if (_editorApiAssembly == null)
throw new InvalidOperationException("The Godot editor API assembly is not loaded.");
- var (assembly, _) = LoadPlugin(assemblyPath, isCollectible: _editorHint);
+ var (assembly, _) = LoadPlugin(assemblyPath, isCollectible: false);
NativeLibrary.SetDllImportResolver(assembly, _dllImportResolver!);
@@ -236,32 +244,29 @@ namespace GodotPlugins
Console.WriteLine("Unloading assembly load context...");
- var alcWeakReference = pluginLoadContext.CreateWeakReference();
-
pluginLoadContext.Unload();
- pluginLoadContext = null;
int startTimeMs = Environment.TickCount;
bool takingTooLong = false;
- while (alcWeakReference.IsAlive)
+ while (pluginLoadContext.IsAlive)
{
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
- if (!alcWeakReference.IsAlive)
+ if (!pluginLoadContext.IsAlive)
break;
int elapsedTimeMs = Environment.TickCount - startTimeMs;
- if (!takingTooLong && elapsedTimeMs >= 2000)
+ if (!takingTooLong && elapsedTimeMs >= 200)
{
takingTooLong = true;
// TODO: How to log from GodotPlugins? (delegate pointer?)
Console.Error.WriteLine("Assembly unloading is taking longer than expected...");
}
- else if (elapsedTimeMs >= 5000)
+ else if (elapsedTimeMs >= 1000)
{
// TODO: How to log from GodotPlugins? (delegate pointer?)
Console.Error.WriteLine(
@@ -273,6 +278,7 @@ namespace GodotPlugins
Console.WriteLine("Assembly load context unloaded successfully.");
+ pluginLoadContext = null;
return true;
}
catch (Exception e)