Merge nucleic/lucid-river-toad-6efj into dev
This commit is contained in:
+31
-2
@@ -64,14 +64,32 @@ public interface IWslc
|
||||
/// <summary>cgroup counters for the resource monitor; null when not running.</summary>
|
||||
Task<ContainerStatsInfo?> ContainerStatsAsync(string name, CancellationToken ct);
|
||||
|
||||
/// <summary>Start a process in a running container. `procId` is minted by the broker and
|
||||
/// keys every event this process emits through <see cref="IBrokerEvents"/>.</summary>
|
||||
/// <summary>
|
||||
/// Create a process in a running container and attach its event handlers, but **do not run
|
||||
/// it** — the caller runs it with <see cref="IWslcProcess.StartAsync"/> once it has sent the
|
||||
/// `procId` downstream. `procId` is minted by the broker and keys every event this process
|
||||
/// emits through <see cref="IBrokerEvents"/>.
|
||||
///
|
||||
/// The two-step split is not ceremony. See <see cref="IWslcProcess.StartAsync"/>.
|
||||
/// </summary>
|
||||
Task<IWslcProcess> ExecAsync(long procId, ProcSpec spec, CancellationToken ct);
|
||||
}
|
||||
|
||||
/// <summary>Control half of a running in-container process (output arrives via events).</summary>
|
||||
public interface IWslcProcess
|
||||
{
|
||||
/// <summary>
|
||||
/// Actually run the process. Separate from <see cref="IWslc.ExecAsync"/> because a short
|
||||
/// command can finish before the `proc.exec` RESPONSE has been written: output and exit ride
|
||||
/// the same ordered outbound queue, so starting first puts `proc.exit` on the wire ahead of
|
||||
/// the `procId` that identifies it, and a client that registers interest on receiving that
|
||||
/// procId waits forever. Observed on hardware with `echo` (docs/WINDOWS_PORT.md §13.3).
|
||||
///
|
||||
/// This is the same reasoning that makes wslc itself split `CreateProcess` from `Start` — so
|
||||
/// handlers can attach before output flows — applied one level up, to the RPC boundary.
|
||||
/// </summary>
|
||||
Task StartAsync(CancellationToken ct);
|
||||
|
||||
Task WriteStdinAsync(ReadOnlyMemory<byte> data, CancellationToken ct);
|
||||
Task CloseStdinAsync(CancellationToken ct);
|
||||
Task SignalAsync(int signal, CancellationToken ct);
|
||||
@@ -107,6 +125,17 @@ public sealed class WslcError(string kind, string message) : Exception(message)
|
||||
/// permanent capability gap, not a transient failure — hostd must not retry.</summary>
|
||||
public const string Unsupported = "unsupported";
|
||||
|
||||
/// <summary>
|
||||
/// A CONTAINER of that name already exists in the session. Distinct from
|
||||
/// <see cref="SessionExists"/> because wslc answers `ERROR_ALREADY_EXISTS` for both and the
|
||||
/// remedies differ completely — remove one container, versus restart the whole WSL stack.
|
||||
///
|
||||
/// Reachable today because this broker's container roster is process-local (there is no
|
||||
/// enumeration on the compat surface), so a container left behind by a crashed broker holds
|
||||
/// its name against every later one. See docs/WINDOWS_PORT.md §13.3.
|
||||
/// </summary>
|
||||
public const string AlreadyExists = "already_exists";
|
||||
|
||||
/// <summary>A session of that name is already running and this facade cannot re-adopt it
|
||||
/// (the compat SDK's `Start()` answers ERROR_ALREADY_EXISTS, and its constructor is lazy, so
|
||||
/// a second handle is not a second session). Distinct from <see cref="StartFailed"/> because
|
||||
|
||||
Reference in New Issue
Block a user