Skip to content

feat(sync): add sentry__cond_wake_all - #1961

Merged
jpnurmi merged 3 commits into
masterfrom
jpnurmi/feat/cond-wake-all
Aug 6, 2026
Merged

feat(sync): add sentry__cond_wake_all#1961
jpnurmi merged 3 commits into
masterfrom
jpnurmi/feat/cond-wake-all

Conversation

@jpnurmi

@jpnurmi jpnurmi commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Add an internal condition-variable broadcast helper and use the platform-native broadcast primitives where available.

This is needed by the threadpool work in #1883: sentry__threadpool_flush() can have multiple concurrent callers waiting on the same condition variable. A single wakeup is not sufficient when the pool drains, because it can release only one waiter and leave other flush callers blocked even though pending already reached zero.

For the pre-Vista Windows fallback, add a bounded WakeAllConditionVariable_PREVISTA implementation that snapshots the current waiter count before issuing wakeups, so newly arriving or re-entering waiters cannot extend the broadcast loop indefinitely.

Based on:

Similar APIs:

#skip-changelog (internal)

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 059cb4d

@jpnurmi
jpnurmi requested a review from JoshuaMoelans August 5, 2026 13:36
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 75.99%. Comparing base (bf4655e) to head (059cb4d).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1961      +/-   ##
==========================================
+ Coverage   75.98%   75.99%   +0.01%     
==========================================
  Files          94       94              
  Lines       22161    22167       +6     
  Branches     3936     3938       +2     
==========================================
+ Hits        16838    16845       +7     
  Misses       4437     4437              
+ Partials      886      885       -1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from jpnurmi/fix/prevista-sync to master August 6, 2026 07:38
@jpnurmi
jpnurmi force-pushed the jpnurmi/feat/cond-wake-all branch from e9a8504 to ad91937 Compare August 6, 2026 07:38

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ad91937. Configure here.

Comment thread src/sentry_sync.h
WakeAllConditionVariable_PREVISTA used to snapshot the waiter count and
then call WakeConditionVariable_PREVISTA once per waiter. Each single-wake
call waits for a waiter-side acknowledgement through ContinueEvent.

That handshake can block forever during broadcast if one of the snapshotted
waiters times out while another waiter is being signaled. The timed-out waiter
can move Waiters past the Target value without setting ContinueEvent, leaving
SignalObjectAndWait stuck even though broadcast should never depend on a
specific waiter resuming.

Release the snapshotted number of semaphore slots directly for wake-all.
This keeps the waiter snapshot atomic, leaves the single-wake compatibility
path unchanged, and makes broadcast tolerant of waiter timeouts. Any racing
timeout may leave a later waiter with a spurious wake, which condition
variable callers already have to handle by re-checking their predicate.
Comment thread src/sentry_sync.h
The pre-Vista wake-all path now releases semaphore slots directly instead
of calling the blocking single-wake helper for every snapshotted waiter.
That avoids the timeout deadlock, but broadcast-woken waiters still run
through the shared waiter acknowledgement code in
SleepConditionVariableCS_PREVISTA.

If Target keeps its previous single-wake value, one of those broadcast
waiters can set ContinueEvent after WakeAllConditionVariable_PREVISTA has
already returned. The event then remains signaled and can be consumed by a
later WakeConditionVariable_PREVISTA call, causing that single wake to
return without a fresh waiter acknowledgement.

Set Target to an impossible waiter count before releasing the broadcast
semaphore slots. This keeps broadcast non-blocking, leaves the single-wake
handshake intact, and prevents wake-all from leaking acknowledgements into
future single-wake operations.
@jpnurmi
jpnurmi merged commit 159d185 into master Aug 6, 2026
103 of 104 checks passed
@jpnurmi
jpnurmi deleted the jpnurmi/feat/cond-wake-all branch August 6, 2026 09:45
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.

2 participants