mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
pm: make sure that interface and scope are always disposed if ctor throws
This fixes an issue wherein dev plugins could end up in a half-disposed state if the ctor were to throw an exception
This commit is contained in:
parent
625a71a6d1
commit
cf4ecacf85
1 changed files with 37 additions and 19 deletions
|
|
@ -412,28 +412,39 @@ internal class LocalPlugin : IDisposable
|
|||
this.ServiceScope = ioc.GetScope();
|
||||
this.ServiceScope.RegisterPrivateScopes(this); // Add this LocalPlugin as a private scope, so services can get it
|
||||
|
||||
if (this.manifest.LoadSync && this.manifest.LoadRequiredState is 0 or 1)
|
||||
try
|
||||
{
|
||||
this.instance = await framework.RunOnFrameworkThread(
|
||||
() => this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!)) as IDalamudPlugin;
|
||||
if (this.manifest.LoadSync && this.manifest.LoadRequiredState is 0 or 1)
|
||||
{
|
||||
this.instance = await framework.RunOnFrameworkThread(
|
||||
() => this.ServiceScope.CreateAsync(
|
||||
this.pluginType!,
|
||||
this.DalamudInterface!)) as IDalamudPlugin;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.instance =
|
||||
await this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!) as IDalamudPlugin;
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.instance =
|
||||
await this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!) as IDalamudPlugin;
|
||||
Log.Error(ex, "Exception in plugin constructor");
|
||||
this.instance = null;
|
||||
}
|
||||
|
||||
if (this.instance == null)
|
||||
{
|
||||
this.State = PluginState.LoadError;
|
||||
this.DalamudInterface.DisposeInternal();
|
||||
this.UnloadAndDisposeState();
|
||||
|
||||
Log.Error(
|
||||
$"Error while loading {this.Name}, failed to bind and call the plugin constructor");
|
||||
"Error while loading {PluginName}, failed to bind and call the plugin constructor", this.InternalName);
|
||||
return;
|
||||
}
|
||||
|
||||
this.State = PluginState.Loaded;
|
||||
Log.Information($"Finished loading {this.DllFile.Name}");
|
||||
Log.Information("Finished loading {PluginName}", this.InternalName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -443,7 +454,7 @@ internal class LocalPlugin : IDisposable
|
|||
if (ex is PluginPreconditionFailedException)
|
||||
Log.Warning(ex.Message);
|
||||
else
|
||||
Log.Error(ex, $"Error while loading {this.Name}");
|
||||
Log.Error(ex, "Error while loading {PluginName}", this.InternalName);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
|
@ -498,15 +509,7 @@ internal class LocalPlugin : IDisposable
|
|||
await framework.RunOnFrameworkThread(() => this.instance?.Dispose());
|
||||
|
||||
this.instance = null;
|
||||
|
||||
this.DalamudInterface?.DisposeInternal();
|
||||
this.DalamudInterface = null;
|
||||
|
||||
this.ServiceScope?.Dispose();
|
||||
this.ServiceScope = null;
|
||||
|
||||
this.pluginType = null;
|
||||
this.pluginAssembly = null;
|
||||
this.UnloadAndDisposeState();
|
||||
|
||||
if (!reloading)
|
||||
{
|
||||
|
|
@ -681,4 +684,19 @@ internal class LocalPlugin : IDisposable
|
|||
throw new InvalidPluginException(this.DllFile);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadAndDisposeState()
|
||||
{
|
||||
if (this.instance != null)
|
||||
throw new InvalidOperationException("Plugin instance should be disposed at this point");
|
||||
|
||||
this.DalamudInterface?.DisposeInternal();
|
||||
this.DalamudInterface = null;
|
||||
|
||||
this.ServiceScope?.Dispose();
|
||||
this.ServiceScope = null;
|
||||
|
||||
this.pluginType = null;
|
||||
this.pluginAssembly = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue