Skip the signal watcher on wasip1 - #2
Open
arena-ai-coding-agent[bot] wants to merge 1 commit into
Open
Conversation
On wasip1, no signal can ever be delivered, but Go's signal watcher goroutine busy-spins (it never idles in single-threaded Wasm). That starves the scheduler, so e.g. the LSP stdin reader never wakes and a running `tsc --lsp --stdio` under node:wasi hangs after responding to `initialize`. Since cancellation can only come from the returned CancelFunc on wasip1, an ordinary context.WithCancel is equivalent and lets the runtime idle in poll_oneoff instead of burning a core. Fixes microsoft#63862 Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes microsoft#63862
Problem
tsc --lsp --stdio(and the--apiserver) callsignal.NotifyContextunconditionally at startup. Onwasip1, signals are never delivered, so Go's signal-watcher goroutine busy-spins (it never gets to idle in single-threaded Wasm). That starves the scheduler: the LSP stdin reader, parked waiting for input, never wakes, so a full LSP session undernode:wasihangs after answeringinitialize, spinning at 100% CPU. CLI invocations (tsc -p) are unaffected for the same reason — they exit before the waiter matters.Implementation
notifyContexthelper intsc/cmd/tsc/notify.go.wasip1it returnscontext.WithCancel(parent)— since no signal can arrive, cancellation can only come from the returnedCancelFunc, so this is equivalent and avoids the busy loop entirely.signal.NotifyContext, so behavior is unchanged.main.go,lsp.go,api.go) through the helper.Tests
No automated test is added: exercising the wasip1 path requires a
wasip1binary run under a WASI host (the issue includes a minimalnode:wasirepro driver, which confirms the hang before the patch and a working initialize/publishDiagnostics/hover/shutdown session after). Native signal handling paths are untouched. The full CI suite runs on this PR.AI assistance disclosure
This patch was authored with AI assistance and has been read and reviewed by the submitting operator before submission.
PR checklist
mainnpx hereby test(running via CI)npx hereby lint(running via CI)npx hereby check:format(running via CI)