Skip to content

Explicitly allow spurious wakeups in emscripten_futex_wait - #27760

Merged
sbc100 merged 1 commit into
emscripten-core:mainfrom
sbc100:futex-wait-docs
Sep 22, 2026
Merged

sbc100 merged 1 commit into
emscripten-core:mainfrom
sbc100:futex-wait-docs

Conversation

@sbc100

@sbc100 sbc100 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

In #26735, emscripten_futex_wait was updated to return -EINTR when
woken via side-channel notifications (_emscripten_thread_notify) or
when a timer fired.

In practice, however, spurious wakeups returning 0 can still occur
(e.g. via races in _emscripten_thread_notify, collateral wakeups on
shared wait addresses, or async wait cancellations). Furthermore,
returning -EINTR could cause functions like sem_timedwait to fail
prematurely (and in musl's __timedwait_cp, EINTR is already
converted to 0 because __eintr_valid_flag is always 0).

Revert the -EINTR reporting so that emscripten_futex_wait matches
the Linux futex(2) contract: any non-error wakeup returns 0, and
callers must always verify their application condition in a loop. When
max_wait_ms is shortened on the main runtime thread to service
_emscripten_next_timer(), track this via timeout_adjusted so that an
early wakeup returns 0 rather than -ETIMEDOUT.

Finally, since no callers check the return value of _emscripten_yield
anymore, change _emscripten_yield and _emscripten_check_timers back
to returning void.

Fixes: #27759

@sbc100
sbc100 requested review from kleisauke and tlively September 21, 2026 23:00

@tlively tlively 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.

Makes sense to me.

@sbc100
sbc100 force-pushed the futex-wait-docs branch 2 times, most recently from fabb519 to 44860ca Compare September 22, 2026 16:36
In emscripten-core#26735, `emscripten_futex_wait` was updated to return `-EINTR` when
woken via side-channel notifications (`_emscripten_thread_notify`) or
when a timer fired.

However, side-channel notifications are not POSIX signals, and returning
`-EINTR` creates the false expectation that a return value of `0`
guarantees the underlying condition was met. In practice, spurious
wakeups returning `0` can still occur (e.g. via races in
`_emscripten_thread_notify`, collateral wakeups on shared wait
addresses, or async wait cancellations). Furthermore, returning
`-EINTR` could cause functions like `sem_timedwait` to fail prematurely.

Revert the `-EINTR` reporting so that `emscripten_futex_wait` matches
the Linux `futex(2)` contract: any non-error wakeup returns `0`, and
callers must always verify their application condition in a loop.

This change has to land after emscripten-core#27755.

Fixes: emscripten-core#27759
@sbc100

sbc100 commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator Author

I make some further cleanups here. PTAL.

@sbc100
sbc100 enabled auto-merge (squash) September 22, 2026 18:16
@sbc100
sbc100 merged commit 29a7eb7 into emscripten-core:main Sep 22, 2026
42 checks passed
@sbc100
sbc100 deleted the futex-wait-docs branch September 22, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

emscripten_futex_wait can return 0 spuriously due to _emscripten_thread_notify race

3 participants