diff --git a/Dalamud/Game/Framework.cs b/Dalamud/Game/Framework.cs index bc1ec2198..f2c65723c 100644 --- a/Dalamud/Game/Framework.cs +++ b/Dalamud/Game/Framework.cs @@ -492,10 +492,7 @@ public sealed class Framework : IDisposable, IServiceType Log.Information("Framework::Destroy!"); Service.Get().Unload(); this.RunPendingTickTasks(); - - // why did we do this here? EntryPoint also does it when the signal is set, what sense does that make - // we should definitely wait for pending tick tasks though - // ServiceManager.UnloadAllServices(); + ServiceManager.WaitForServiceUnload(); Log.Information("Framework::Destroy OK!"); return this.destroyHook.OriginalDisposeSafe(framework); diff --git a/Dalamud/ServiceManager.cs b/Dalamud/ServiceManager.cs index c49a78b11..eb4c2eb51 100644 --- a/Dalamud/ServiceManager.cs +++ b/Dalamud/ServiceManager.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using Dalamud.Configuration.Internal; @@ -35,6 +36,8 @@ internal static class ServiceManager private static readonly TaskCompletionSource BlockingServicesLoadedTaskCompletionSource = new(); private static readonly List LoadedServices = new(); + + private static ManualResetEvent unloadResetEvent = new(false); /// /// Kinds of services. @@ -285,6 +288,8 @@ internal static class ServiceManager return; } + unloadResetEvent.Reset(); + var dependencyServicesMap = new Dictionary>(); var allToUnload = new HashSet(); var unloadOrder = new List(); @@ -351,6 +356,16 @@ internal static class ServiceManager { LoadedServices.Clear(); } + + unloadResetEvent.Set(); + } + + /// + /// Wait until all services have been unloaded. + /// + public static void WaitForServiceUnload() + { + unloadResetEvent.WaitOne(); } ///