Document CmdPal lifecycle contracts

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 7a42451c-0ec4-4778-86fd-c77d7ac9d122
This commit is contained in:
Michael Jolley
2026-08-27 19:48:44 -05:00
parent 88238db78b
commit 407ce5c696
2 changed files with 6 additions and 0 deletions

View File

@@ -51,6 +51,9 @@ internal static class ExtensionTaskCoordinator
});
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
// Cancellation is not partial success. The current reload may stop here, and the next
// reload stops every service before rediscovering all providers.
cancellationToken.ThrowIfCancellationRequested();
return results.OfType<TResult>().ToArray();
}

View File

@@ -82,6 +82,9 @@ public sealed partial class JsonRpcExtensionService : IExtensionService, IDispos
private static readonly string ExtensionsPath = GetDefaultExtensionsPath();
private readonly TaskScheduler _taskScheduler;
// This gate lives for the service lifetime. Disposing it while a start owns a permit
// could make its matching Release throw.
private readonly SemaphoreSlim _extensionStartupGate = new(MaxConcurrentExtensionStarts, MaxConcurrentExtensionStarts);
private readonly Lock _extensionsLock = new();
private readonly List<JSExtensionWrapper> _extensions = [];