fix(process): cancel run-token reads during sampling

Propagate the sample AbortSignal through readProcessRunId to host environment inspection so cancellation can settle a blocked ownership-token read.

Validation: ownership and capture lifecycle suites pass, including an abort-waiting host regression. Native provider runtime behavior was not exercised.
This commit is contained in:
morluto
2026-10-12 04:33:42 +08:00
parent f64790bfc3
commit 09b6828516
3 changed files with 31 additions and 2 deletions
@@ -0,0 +1,28 @@
import { expect, it } from "vitest";
import type { ProcessOwnershipHost } from "./ProcessOwnership.js";
import { readProcessRunId } from "./ProcessOwnership.js";
it("passes cancellation through run-token reads", async () => {
const controller = new AbortController();
const cancellation = new Error("cancelled");
const host: ProcessOwnershipHost = {
listProcesses: async () => [],
environment: async (_pid, signal) => {
if (signal === undefined) throw new Error("run-token signal was omitted");
return await new Promise<Readonly<Record<string, string>>>(
(_resolve, reject) => {
signal.addEventListener("abort", () => reject(signal.reason), {
once: true,
});
},
);
},
signalGroup: () => undefined,
};
const reading = readProcessRunId(42, host, controller.signal);
controller.abort(cancellation);
await expect(reading).rejects.toBe(cancellation);
});
+2 -1
View File
@@ -223,8 +223,9 @@ const systemWindowsProcessTreeHost: WindowsProcessTreeHost = {
export const readProcessRunId = async (
pid: number,
host: ProcessOwnershipHost = systemHost,
signal?: AbortSignal,
): Promise<string | undefined> =>
(await host.environment(pid)).REA_PROCESS_RUN_ID;
(await host.environment(pid, signal)).REA_PROCESS_RUN_ID;
/** Token-validate every rooted POSIX process group before signaling any. */
export const cleanupOwnedProcessGroup = async (
+1 -1
View File
@@ -358,7 +358,7 @@ const inspectInitializedPtyRoot = async (
return undefined;
let observedRunId: string | undefined;
try {
observedRunId = await readProcessRunId(rootPid);
observedRunId = await readProcessRunId(rootPid, undefined, signal);
} catch (cause: unknown) {
// Unreadable run identity means the root cannot be attributed.
void cause;