microsoft / microsoft/vscode-wasm

Feature request: Allow I/O multiplexing without threads

Open
#235 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature-request
Dominant language
TypeScript
Stars
456
Forks
40
Avg merge
3d 2h
Merged PRs (30d)
4

Description

I am making a WASM-based language service running completely within VS Code powered by the WASM execution engine extension. During the porting process, I noticed some missing feature that kept my language server from establishing the connection properly. After much investigation, I pinpointed the concrete requirements in WASI Preview 1's I/O handling to enable proper cooperative I/O multiplexing in WebAssembly programs without resorting to the threads extension.

First of all, I admit my use case is niche. The language server of interest, Agda language server, is written in Haskell and can be compiled with the Glasgow Haskell Compiler (GHC). Its WASM backend (specifically its runtime, RTS) does not yet have thread support. Without a threaded RTS, the Haskell program can still operate concurrently, but given an average best-effort WASI implementation, it is likely unable to maintain a duplex communication with the client.

Specifically, I propose changes on VS Code's WASM execution engine to (1.) provide a nonblocking way to read stdin-pipes and (2.) implement the blocking behavior in poll_oneoff to better align with POSIX-like I/O expectations on multiplexing.

1. Non-blocking stdin reads

  • Current behavior: fd_read() on stdin blocks indefinitely when no input is available, leading to starvation.
  • Proposed behavior: Allow fd_read() on stdin to return EAGAIN (WasiError.again) when no input is available, enabling non-blocking operation.
  • Benefits: This change prevents runtime softlocks in cooperative schedulers, enables standard non-blocking I/O patterns, without affecting existing program expecting blocking behavior. I expect this to be a minor interface change.

2. Correct poll_oneoff blocking on stdin

  • Current behavior: poll_oneoff returns immediately even when subscriptions expect blocking on stdin readiness.
  • Proposed behavior: poll_oneoff should block when subscriptions specify waiting for stdin to become readable and there is no clock event present, resembling the POSIX select() semantics.
  • Benefits: This enables proper event-driven I/O multiplexing, fixes broken assumptions in runtimes that rely on blocking poll behavior, and improves WASI's fidelity to standard I/O models. This would be very complex compared to 1., but since my only concern is stdin, it is possible to apply enough hacks just for my use case.

References

Here is my study of non-blocking reads on various WASM runtimes. A PoC implementation can be found in the fork agda-web/vscode-wasm. I am available to provide more context and assist the shaping if needed.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by examining the WASI fd_read and poll_oneoff entry points and compare their current behavior with the requirements in the issue. Review the linked study and agda-web/vscode-wasm PoC for context. Done means stdin reads can return WasiError.again when appropriate and poll_oneoff blocks for stdin readiness without a clock event.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vscode, wasm
Domain
backend, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.