wasm-posix-host
    Preparing search index...

    Class CentralizedKernelWorker

    Index

    Constructors

    Properties

    relistenBatchSize: number = 64

    How many syscalls to process via microtask before yielding to the event loop via setImmediate. Default 64 is optimal for Node.js. Set to 1 in browser environments where the kernel runs on the main thread.

    usePolling: boolean = false

    When true, use a MessageChannel-based poller to check all channels instead of per-channel Atomics.waitAsync listeners.

    This avoids a V8 bug where Atomics.waitAsync microtask chains from multiple concurrent processes freeze the main thread. The poller uses MessageChannel for ~0ms dispatch (bypassing the browser's 4ms timer clamp on setTimeout/setInterval), with periodic setTimeout yields every 4ms to keep timers and rendering alive.

    Enable this in browser environments where the kernel runs on the main thread. In Node.js (where setImmediate is native), the default event-driven mode (Atomics.waitAsync) is preferred.

    Accessors

    • get framebuffers(): FramebufferRegistry

      Live /dev/fb0 mappings reported by the kernel, indexed by pid. Renderers (canvas in browser, no-op in Node) read from this on each frame; the kernel populates it via the host_bind_framebuffer import.

      Returns FramebufferRegistry

    Methods

    • Add a new channel (e.g. for a thread) to an existing process registration. Uses the process's existing memory. If tid is provided, tracks the mapping so handleExit can identify thread exits. threadFnPtr / threadArgPtr are stored when the thread was created via clone() so handleFork can route a fork() from this thread back through its entry point.

      Parameters

      • pid: number
      • channelOffset: number
      • Optionaltid: number
      • OptionalthreadFnPtr: number
      • OptionalthreadArgPtr: number

      Returns void

    • Allocate a fresh pid for a top-level spawn from a host. Skips any pids already in the kernel's process table (forked children, the virtual init at pid 1, etc.). The host is no longer expected to pick pids; this is the single source of truth.

      Returns number

    • Append data to a process's stdin buffer without marking stdin as a pipe. Used for interactive stdin where data arrives incrementally. Wakes any blocked stdin readers after appending.

      Parameters

      • pid: number
      • data: Uint8Array

      Returns void

    • Channel count the program last configured on /dev/dsp.

      Returns number

    • Bytes buffered in the /dev/dsp ring waiting to be drained.

      Returns number

    • Sample rate (Hz) the program last configured on /dev/dsp.

      Returns number

    • Drain up to out.byteLength bytes of PCM audio buffered in /dev/dsp into out. Returns the number of bytes copied, always a multiple of the active frame size (2 bytes mono / 4 bytes stereo).

      The host typically drives this from an AudioWorkletNode or AudioBufferSourceNode scheduler that pulls samples at the rate an AudioContext reports. The kernel ring drops oldest frames on overflow rather than blocking, so falling behind a few RAFs costs audio but never wedges DOOM.

      Parameters

      • out: Uint8Array

      Returns number

    • Dump syscall profiling data to stderr. Call from your serve script: process.on('SIGINT', () => { kernelWorker.dumpProfile(); process.exit(); });

      Only produces output when WASM_POSIX_PROFILE=1 env var is set.

      Returns void

    • Per-process fork counter (parent side, incremented inside kernel_fork_process on success). Used by the spawn regression tests to assert that a SYS_SPAWN call did NOT fall back to the fork path.

      Returns u64::MAX (as bigint) if the pid does not exist; callers should compare against an explicit before-value rather than treating "no process" as "0 forks".

      Parameters

      • pid: number

      Returns bigint

    • ABI version the kernel advertised at startup via its __abi_version export. Worker processes compare against this and refuse to run programs built against an incompatible ABI.

      Returns number

    • Get the kernel Wasm instance.

      Returns Instance | null

    • Return the wasm Memory for pid (or undefined if no such process is registered). Renderers use this to build typed-array views over the bound framebuffer region.

      Parameters

      • pid: number

      Returns Memory | undefined

    • Initialize the kernel. Loads kernel Wasm and validates the host adapter ABI.

      Parameters

      • kernelWasmBytes: BufferSource

      Returns Promise<void>

    • Push a mouse event into the kernel's /dev/input/mice queue. The kernel buffers a 3-byte PS/2 frame; any process blocked in read() or poll() on the device is woken on the next retry tick.

      Parameters

      • dx: number
      • dy: number
      • buttons: number

      Returns void

    • Run kernel-side exec setup: close CLOEXEC fds, reset signal handlers. Returns 0 on success, negative errno on failure. Called by onExec callbacks after confirming the target program exists.

      Parameters

      • pid: number

      Returns number

    • Notify the kernel that a host worker for pid died asynchronously (uncaught wasm trap, instantiation failure, externally terminated Worker) WITHOUT going through the normal SYS_EXIT_GROUP path.

      Without this, an OOB/instantiation crash leaves the kernel believing the process is still alive: any concurrent waitpid in the parent then blocks until host destroy. P-06 / K-03 exposed this — the child's wasm trapped during _start, the worker reported it via {type:"error"}, the host posted stderr + deactivated the process locally, but the kernel never marked the pid as a zombie or woke the parent.

      Marks the process as signal-terminated in Rust using signum (default SIGSEGV = 11), queues SIGCHLD on the parent, and wakes any parked waitpid / waitid.

      Idempotent via hostReaped: if the kernel already saw a clean SYS_EXIT for this pid, this is a no-op (the kernel's exit status wins). Host-side cleanup (channel removal, timer cancellation) is still the caller's responsibility — call deactivateProcess after this if the pid is going away.

      Parameters

      • pid: number
      • signum: number = 11

      Returns void

    • Public wake helper for host-side pipe writes (TCP bridges, HTTP bridges, etc.). Call this AFTER directly writing into a pipe via kernel_pipe_write or kernel_inject_connection.

      In order:

      1. Wake any process blocked in read/recv on this pipe (pendingPipeReaders).
      2. Wake any process blocked in poll/ppoll/pselect6 whose pipeIndices includes this pipe (pendingPollRetries). Pass pidFilter to restrict the wake to a single owning pid — used by the Node TCP bridge when dispatching an inbound connection to a specific listener.
      3. Schedule a broad wake (scheduleWakeBlockedRetries) for everything else.

      Without step 2, blocked pollers wait for the fallback timer in handleBlockingRetry to fire, which is the bug behind PR fixing the WordPress LAMP demo's slow install.php (see commit history).

      Parameters

      • pipeIdx: number
      • OptionalpidFilter: number

      Returns void

    • Public wake helper for host-side pipe reads (response pump in the TCP/HTTP bridges). Call this AFTER directly reading data from a pipe so any process blocked writing because the pipe was full can resume, plus a broad wake.

      Parameters

      • pipeIdx: number

      Returns void

    • Notify the kernel that a thread has exited. Removes thread state from the process's thread table.

      Parameters

      • pid: number
      • tid: number

      Returns void

    • Register a callback for PTY output data.

      Parameters

      • ptyIdx: number
      • callback: (data: Uint8Array) => void

      Returns void

    • Pick the next listener target for a port via round-robin. Only considers processes that are still registered.

      Public so external callers (the in-kernel HTTP request bridge) can resolve a port to a {pid, fd} before injecting a connection.

      Parameters

      • port: number

      Returns { fd: number; pid: number } | null

    • Remove old channel/registration state for a process about to exec. Does NOT remove from kernel process table (exec keeps the same pid). Does NOT cancel timers (POSIX: timers are preserved across exec).

      Parameters

      • pid: number

      Returns void

    • Read all available data from a PTY master (slave output → host). Returns data or null if empty.

      Parameters

      • ptyIdx: number

      Returns Uint8Array<ArrayBufferLike> | null

    • Write data to a PTY master (host → line discipline → slave). Wakes any process blocked on reading the slave side.

      Parameters

      • ptyIdx: number
      • data: Uint8Array

      Returns void

    • Resize a PTY and send SIGWINCH to the foreground process group.

      Parameters

      • ptyIdx: number
      • rows: number
      • cols: number

      Returns void

    • Read /proc/[pid]/maps for a foreign process. Returns the raw Linux- style text (one line per mapped region) or null if the pid doesn't exist. Empty string if the process has no mappings.

      Parameters

      • pid: number

      Returns string | null

    • Register a process and its thread channels with the kernel. Each channel is a region in the process's shared Memory.

      Parameters

      • pid: number
      • memory: Memory
      • channelOffsets: number[]
      • Optionaloptions: RegisterProcessOptions

      Returns void

    • Remove a channel from a process registration (e.g. when a thread exits).

      Parameters

      • pid: number
      • channelOffset: number

      Returns void

    • Remove a process from the kernel's PROCESS_TABLE. Called when a zombie is reaped by wait/waitpid.

      Parameters

      • pid: number

      Returns void

    • Remove a pid from the wasm kernel's ProcessTable entirely. Used by the worker-entry's crash path: when a worker dies via a wasm trap (signature mismatch, OOM, etc.) the kernel never saw a SYS_EXIT, so its ProcessTable still has the pid in state=Running. After this runs, kernel_enum_procs no longer reports it and a parent's waitpid() returns ECHILD — accurate for "the process really is gone."

      Don't call this for normal exits — the kernel marks those Exited (zombie) so the parent can still reap.

      Parameters

      • pid: number

      Returns void

    • Parameters

      • pid: number
      • len: number

      Returns number

    • Parameters

      • pid: number
      • addr: number
      • len: number

      Returns number

    • Send an HTTP/1.1 request to a server running inside the kernel and resolve with the parsed response. Bypasses real TCP — uses kernel_inject_connection + kernel_pipe_* directly.

      Used by both the browser service-worker bridge and the Node host's fetchInKernel API (see docs/plans/2026-04-30-external-kernel-http-request-interface.md).

      Parameters

      • port: number
      • request: HttpRequest
      • opts: SendHttpRequestOptions = {}

      Returns Promise<HttpResponse>

    • Set the program's initial brk. Compact process layouts pass the first guest-managed byte after the host control slab; legacy callers may pass the program's __heap_base directly. Must run before the new process worker can issue its first syscall.

      Accepts bigint (preferred — what extractHeapBase returns) or number. The kernel export takes a usize, whose JS representation depends on the kernel wasm pointer width.

      Parameters

      • pid: number
      • addr: number | bigint

      Returns boolean

    • Set the program-break ceiling for a process. Hosts use this to reserve low in-memory control pages for syscall channels and pthread TLS without letting brk grow into them.

      Parameters

      • pid: number
      • brkLimit: number

      Returns boolean

    • Set a freshly-created process's initial real/effective uid and gid. Must be called after registerProcess and before the process starts.

      Parameters

      • pid: number
      • ids: { gid?: number; uid?: number }

      Returns void

    • Set the working directory for a process. Must be called after registerProcess and before the process starts.

      Parameters

      • pid: number
      • cwd: string

      Returns void

    • Set the mmap address space ceiling for a process. Must be called before the process worker starts to prevent mmap from allocating in the thread channel/TLS region.

      Parameters

      • pid: number
      • maxAddr: number

      Returns void

    • Set the automatic mmap lower bound for a process. Compact process layouts set this to the first guest-managed byte after the host control prefix.

      Parameters

      • pid: number
      • mmapBase: number

      Returns boolean

    • Set the next child PID to allocate.

      Parameters

      • pid: number

      Returns void

    • Set stdout/stderr capture callbacks on the underlying kernel instance. Must be called after construction but works at any time.

      Parameters

      • callbacks: { onStderr?: (data: Uint8Array) => void; onStdout?: (data: Uint8Array) => void }

      Returns void

    • Provide data that will be returned when the process reads from stdin (fd 0). Data is returned in chunks until exhausted, then EOF is returned. Must be called before the process starts reading stdin.

      Parameters

      • pid: number
      • data: Uint8Array

      Returns void

    • Create a PTY pair and wire fds 0/1/2 of pid to the slave side. Returns the PTY index, or throws on failure.

      Parameters

      • pid: number

      Returns number

    • Parameters

      • value: number | bigint

      Returns KernelPointer

    • Unregister a process. Stops listening on its channels and removes it from the kernel's process table.

      Parameters

      • pid: number

      Returns void