mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-15 21:24:16 +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 = ioc.GetScope();
|
||||||
this.ServiceScope.RegisterPrivateScopes(this); // Add this LocalPlugin as a private scope, so services can get it
|
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(
|
if (this.manifest.LoadSync && this.manifest.LoadRequiredState is 0 or 1)
|
||||||
() => this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!)) as IDalamudPlugin;
|
{
|
||||||
|
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 =
|
Log.Error(ex, "Exception in plugin constructor");
|
||||||
await this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!) as IDalamudPlugin;
|
this.instance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.instance == null)
|
if (this.instance == null)
|
||||||
{
|
{
|
||||||
this.State = PluginState.LoadError;
|
this.State = PluginState.LoadError;
|
||||||
this.DalamudInterface.DisposeInternal();
|
this.UnloadAndDisposeState();
|
||||||
|
|
||||||
Log.Error(
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.State = PluginState.Loaded;
|
this.State = PluginState.Loaded;
|
||||||
Log.Information($"Finished loading {this.DllFile.Name}");
|
Log.Information("Finished loading {PluginName}", this.InternalName);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -443,7 +454,7 @@ internal class LocalPlugin : IDisposable
|
||||||
if (ex is PluginPreconditionFailedException)
|
if (ex is PluginPreconditionFailedException)
|
||||||
Log.Warning(ex.Message);
|
Log.Warning(ex.Message);
|
||||||
else
|
else
|
||||||
Log.Error(ex, $"Error while loading {this.Name}");
|
Log.Error(ex, "Error while loading {PluginName}", this.InternalName);
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
@ -498,15 +509,7 @@ internal class LocalPlugin : IDisposable
|
||||||
await framework.RunOnFrameworkThread(() => this.instance?.Dispose());
|
await framework.RunOnFrameworkThread(() => this.instance?.Dispose());
|
||||||
|
|
||||||
this.instance = null;
|
this.instance = null;
|
||||||
|
this.UnloadAndDisposeState();
|
||||||
this.DalamudInterface?.DisposeInternal();
|
|
||||||
this.DalamudInterface = null;
|
|
||||||
|
|
||||||
this.ServiceScope?.Dispose();
|
|
||||||
this.ServiceScope = null;
|
|
||||||
|
|
||||||
this.pluginType = null;
|
|
||||||
this.pluginAssembly = null;
|
|
||||||
|
|
||||||
if (!reloading)
|
if (!reloading)
|
||||||
{
|
{
|
||||||
|
|
@ -681,4 +684,19 @@ internal class LocalPlugin : IDisposable
|
||||||
throw new InvalidPluginException(this.DllFile);
|
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