FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

lib: keep event loop alive for pending Atomics.waitAsync by igor-shevelenkov · Pull Request #61982 · nodejs/node · GitHub

/ node Public

lib: keep event loop alive for pending Atomics.waitAsync - #61982

Closed
igor-shevelenkov wants to merge 1 commit into
nodejs:mainfrom
igor-shevelenkov:fix/atomics-waitasync-event-loop-ref
Closed

lib: keep event loop alive for pending Atomics.waitAsync#61982
igor-shevelenkov wants to merge 1 commit into
nodejs:mainfrom
igor-shevelenkov:fix/atomics-waitasync-event-loop-ref

Conversation

Copy link
Copy Markdown
Contributor

Summary

Fixes #61941.

Pending Atomics.waitAsync() operations now keep the Node.js event loop alive until they settle, so the process does not exit early when the wait is the only pending async operation.

Problem

Atomics.waitAsync() returns a promise-like result, but that pending wait did not ref the event loop.
If nothing else was ref'd, Node could terminate before Atomics.notify() (or timeout) resolved the wait.

This affects real-world patterns like multithreaded WASM / Emscripten where completion is signaled via atomics from non-libuv worker activity.

Approach

Introduced internal/atomics/wait_async with trackWaitAsyncResult(result):

  • Leaves sync results (result.async === false) untouched.
  • Tracks async waiters with a counter.
  • Starts one shared ref'd keepalive interval when the first async waiter appears.
  • Attaches settle handlers to decrement the counter on both resolve and reject.
  • Clears the keepalive interval when the last waiter settles.

Integrated this in two places:

  1. lib/internal/bootstrap/node.js
    Wrap globalThis.Atomics.waitAsync so userland calls are tracked.

  2. lib/internal/worker/messaging.js
    Wrap internal primordial AtomicsWaitAsync usage so postMessageToThread() also keeps the loop alive while awaiting the shared-status wait.

Tests

Added regression coverage:

  • test/parallel/test-atomics-waitasync-event-loop.mjs

    • notify path
    • timeout path
    • concurrent waiters
    • sync not-equal path
    • constructor/prototype invariants
  • test/parallel/test-worker-messaging-event-loop-ref.mjs

    • verifies postMessageToThread() internal wait path does not allow early process exit

Notes

This is a Node-side lifecycle fix around the V8-provided waitAsync result, preserving existing API behavior while correcting event-loop liveness semantics.

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/startup

nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. worker Issues and PRs related to Worker support. labels Feb 25, 2026

Renegade334 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Replacing global-scope ES builtins with proxies is a big no-no. Resolving the issues in #44409 will be the correct way forward.

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

Labels

lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. worker Issues and PRs related to Worker support.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Atomics.waitAsync() promise does not ref the event loop

3 participants


Back | FazBrowse Home | New Git URL