diff --git a/Dalamud/ServiceManager.cs b/Dalamud/ServiceManager.cs
index bdc0918b0..75daf9187 100644
--- a/Dalamud/ServiceManager.cs
+++ b/Dalamud/ServiceManager.cs
@@ -43,6 +43,7 @@ internal static class ServiceManager
#endif
private static readonly TaskCompletionSource BlockingServicesLoadedTaskCompletionSource = new();
+ private static readonly CancellationTokenSource UnloadCancellationTokenSource = new();
private static ManualResetEvent unloadResetEvent = new(false);
@@ -107,6 +108,12 @@ internal static class ServiceManager
/// Gets task that gets completed when all blocking early loading services are done loading.
///
public static Task BlockingResolved { get; } = BlockingServicesLoadedTaskCompletionSource.Task;
+
+ ///
+ /// Gets a cancellation token that will be cancelled once Dalamud needs to unload, be it due to a failure state
+ /// during initialization or during regular operation.
+ ///
+ public static CancellationToken UnloadCancellationToken => UnloadCancellationTokenSource.Token;
///
/// Initializes Provided Services and FFXIVClientStructs.
@@ -374,6 +381,8 @@ internal static class ServiceManager
}
catch (Exception e)
{
+ UnloadCancellationTokenSource.Cancel();
+
Log.Error(e, "Failed resolving services");
try
{
@@ -401,6 +410,8 @@ internal static class ServiceManager
///
public static void UnloadAllServices()
{
+ UnloadCancellationTokenSource.Cancel();
+
var framework = Service.GetNullable(Service.ExceptionPropagationMode.None);
if (framework is { IsInFrameworkUpdateThread: false, IsFrameworkUnloading: false })
{
diff --git a/Dalamud/Service{T}.cs b/Dalamud/Service{T}.cs
index 165257ef5..a4d404e18 100644
--- a/Dalamud/Service{T}.cs
+++ b/Dalamud/Service{T}.cs
@@ -116,7 +116,7 @@ internal static class Service where T : IServiceType
#endif
if (!instanceTcs.Task.IsCompleted)
- instanceTcs.Task.Wait();
+ instanceTcs.Task.Wait(ServiceManager.UnloadCancellationToken);
return instanceTcs.Task.Result;
}