mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-31 12:53:41 +01:00
fix: prevent some deadlocks in profile management code
We can never load/unload plugins synchronously, since they might need to get back on framework thread to unload. Also fixes an issue wherein applying might have gotten stuck if an unload threw an exception.
This commit is contained in:
parent
da8bbf5a28
commit
c3fe41640e
7 changed files with 107 additions and 88 deletions
|
|
@ -2367,12 +2367,12 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
{
|
||||
if (inProfile)
|
||||
{
|
||||
Task.Run(() => profile.AddOrUpdate(plugin.Manifest.InternalName, true))
|
||||
Task.Run(() => profile.AddOrUpdateAsync(plugin.Manifest.InternalName, true))
|
||||
.ContinueWith(this.DisplayErrorContinuation, Locs.Profiles_CouldNotAdd);
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(() => profile.Remove(plugin.Manifest.InternalName))
|
||||
Task.Run(() => profile.RemoveAsync(plugin.Manifest.InternalName))
|
||||
.ContinueWith(this.DisplayErrorContinuation, Locs.Profiles_CouldNotRemove);
|
||||
}
|
||||
}
|
||||
|
|
@ -2391,14 +2391,17 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Times))
|
||||
{
|
||||
profileManager.DefaultProfile.AddOrUpdate(plugin.Manifest.InternalName, plugin.IsLoaded, false);
|
||||
// TODO: Work this out
|
||||
Task.Run(() => profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.InternalName, plugin.IsLoaded, false))
|
||||
.GetAwaiter().GetResult();
|
||||
foreach (var profile in profileManager.Profiles.Where(x => !x.IsDefaultProfile && x.Plugins.Any(y => y.InternalName == plugin.Manifest.InternalName)))
|
||||
{
|
||||
profile.Remove(plugin.Manifest.InternalName, false);
|
||||
Task.Run(() => profile.RemoveAsync(plugin.Manifest.InternalName, false))
|
||||
.GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
// TODO error handling
|
||||
Task.Run(() => profileManager.ApplyAllWantStates());
|
||||
Task.Run(profileManager.ApplyAllWantStatesAsync)
|
||||
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_ProfileApplyFail);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
|
@ -2448,7 +2451,9 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
profileManager.DefaultProfile.AddOrUpdate(plugin.Manifest.InternalName, false, false);
|
||||
// TODO: Work this out
|
||||
Task.Run(() => profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.InternalName, false, false))
|
||||
.GetAwaiter().GetResult();
|
||||
this.enableDisableStatus = OperationStatus.Complete;
|
||||
|
||||
notifications.AddNotification(Locs.Notifications_PluginDisabled(plugin.Manifest.Name), Locs.Notifications_PluginDisabledTitle, NotificationType.Success);
|
||||
|
|
@ -2466,7 +2471,9 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
plugin.ReloadManifest();
|
||||
}
|
||||
|
||||
profileManager.DefaultProfile.AddOrUpdate(plugin.Manifest.InternalName, true, false);
|
||||
// TODO: Work this out
|
||||
Task.Run(() => profileManager.DefaultProfile.AddOrUpdateAsync(plugin.Manifest.InternalName, true, false))
|
||||
.GetAwaiter().GetResult();
|
||||
|
||||
var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer))
|
||||
.ContinueWith(
|
||||
|
|
@ -3282,6 +3289,8 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
|
||||
public static string ErrorModal_UpdaterFatal => Loc.Localize("InstallerUpdaterFatal", "Failed to update plugins.\nPlease restart your game and try again. If this error occurs again, please complain.");
|
||||
|
||||
public static string ErrorModal_ProfileApplyFail => Loc.Localize("InstallerProfileApplyFail", "Failed to process collections.\nPlease restart your game and try again. If this error occurs again, please complain.");
|
||||
|
||||
public static string ErrorModal_UpdaterFail(int failCount) => Loc.Localize("InstallerUpdaterFail", "Failed to update {0} plugins.\nPlease restart your game and try again. If this error occurs again, please complain.").Format(failCount);
|
||||
|
||||
public static string ErrorModal_UpdaterFailPartial(int successCount, int failCount) => Loc.Localize("InstallerUpdaterFailPartial", "Updated {0} plugins, failed to update {1}.\nPlease restart your game and try again. If this error occurs again, please complain.").Format(successCount, failCount);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ internal class ProfileManagerWidget
|
|||
var isEnabled = profile.IsEnabled;
|
||||
if (ImGuiComponents.ToggleButton($"###toggleButton{profile.Guid}", ref isEnabled))
|
||||
{
|
||||
Task.Run(() => profile.SetState(isEnabled))
|
||||
Task.Run(() => profile.SetStateAsync(isEnabled))
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotChangeState);
|
||||
}
|
||||
|
||||
|
|
@ -228,9 +228,7 @@ internal class ProfileManagerWidget
|
|||
|
||||
if (ImGui.Selectable($"{plugin.Manifest.Name}###selector{plugin.Manifest.InternalName}"))
|
||||
{
|
||||
// TODO this sucks
|
||||
profile.AddOrUpdate(plugin.Manifest.InternalName, true, false);
|
||||
Task.Run(() => profman.ApplyAllWantStates())
|
||||
Task.Run(() => profile.AddOrUpdateAsync(plugin.Manifest.InternalName, true, false))
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotChangeState);
|
||||
}
|
||||
}
|
||||
|
|
@ -273,8 +271,12 @@ internal class ProfileManagerWidget
|
|||
this.Reset();
|
||||
|
||||
// DeleteProfile() is sync, it doesn't apply and we are modifying the plugins collection. Will throw below when iterating
|
||||
profman.DeleteProfile(profile);
|
||||
Task.Run(() => profman.ApplyAllWantStates())
|
||||
// TODO: DeleteProfileAsync should probably apply as well
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await profman.DeleteProfileAsync(profile);
|
||||
await profman.ApplyAllWantStatesAsync();
|
||||
})
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
this.installer.DisplayErrorContinuation(t, Locs.ErrorCouldNotChangeState);
|
||||
|
|
@ -300,7 +302,7 @@ internal class ProfileManagerWidget
|
|||
var isEnabled = profile.IsEnabled;
|
||||
if (ImGuiComponents.ToggleButton($"###toggleButton{profile.Guid}", ref isEnabled))
|
||||
{
|
||||
Task.Run(() => profile.SetState(isEnabled))
|
||||
Task.Run(() => profile.SetStateAsync(isEnabled))
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotChangeState);
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +393,7 @@ internal class ProfileManagerWidget
|
|||
var enabled = plugin.IsEnabled;
|
||||
if (ImGui.Checkbox($"###{this.editingProfileGuid}-{plugin.InternalName}", ref enabled))
|
||||
{
|
||||
Task.Run(() => profile.AddOrUpdate(plugin.InternalName, enabled))
|
||||
Task.Run(() => profile.AddOrUpdateAsync(plugin.InternalName, enabled))
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotChangeState);
|
||||
}
|
||||
|
||||
|
|
@ -411,9 +413,8 @@ internal class ProfileManagerWidget
|
|||
if (wantRemovePluginInternalName != null)
|
||||
{
|
||||
// TODO: handle error
|
||||
profile.Remove(wantRemovePluginInternalName, false);
|
||||
Task.Run(() => profman.ApplyAllWantStates())
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotRemove);
|
||||
Task.Run(() => profile.RemoveAsync(wantRemovePluginInternalName, false))
|
||||
.ContinueWith(this.installer.DisplayErrorContinuation, Locs.ErrorCouldNotRemove);
|
||||
}
|
||||
|
||||
if (!didAny)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue