/** * Deadline interruption for pyodide, which executes on THIS thread: a * busy guest loop blocks the event loop, so no timer here can ever * fire (the quickjs runtime has an in-VM interrupt hook for this; * pyodide only reads a SharedArrayBuffer via setInterruptBuffer). A * tiny watchdog worker owns the countdown instead: it writes SIGINT * (2) into the shared interrupt cell at the deadline, pyodide's * interpreter loop sees it mid-execution and raises KeyboardInterrupt, * and the run reports which trip happened through the second cell. * * Cells (Int32Array over one SharedArrayBuffer): [0] the pyodide * interrupt cell (pyodide resets it to 0 when it fires), [1] why the * trip happened (1 deadline, 2 kill signal), [2] the arm generation, * which the watchdog re-checks at the deadline so a countdown * cancelled just as it fires cannot poison the next run. * * Environments without SharedArrayBuffer or workers (a browser page * that is not cross-origin isolated) get null: runs stay unbounded * there, exactly the pre-interrupt behavior. */ interface ArmedInterrupt { /** Stop the countdown; report the trip, once (idempotent: null after). */ disarm(): 'deadline' | 'signal' | null; } export interface PyodideInterrupter { /** The view to hand to pyodide.setInterruptBuffer, once. */ readonly view: Int32Array; arm(timeoutSeconds: number | null, signal?: AbortSignal): ArmedInterrupt; close(): void; } export declare function createPyodideInterrupter(): Promise; export {}; //# sourceMappingURL=interrupt.d.ts.map