Fixing future::wait_until (and wait_for) to return once future was made ready#7367
Fixing future::wait_until (and wait_for) to return once future was made ready#7367hkaiser wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (8)
🚧 Files skipped from review as they are similar to previous changes (7)
📝 WalkthroughSummary by CodeRabbit
WalkthroughTimed suspension APIs now accept move-only predicates and return ChangesPredicate-aware timed suspension
Scoped lock guards
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant FutureData
participant ConditionVariable
participant ExecutionAgent
participant WaitPredicate
FutureData->>ConditionVariable: wait_until with readiness predicate
ConditionVariable->>ExecutionAgent: sleep_until with wait_cond
ExecutionAgent->>WaitPredicate: evaluate condition
WaitPredicate-->>ExecutionAgent: true or false
ExecutionAgent-->>ConditionVariable: signaled or timeout
ConditionVariable-->>FutureData: wait result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Up to standards ✅🟢 Issues
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/core/execution_base/tests/unit/execution_context.cpp`:
- Around line 56-64: Return an explicit threads::thread_restart_state::timeout
value from both sleep_for and sleep_until overrides, matching default_agent
behavior and preventing non-void functions from reaching the end without
returning.
In `@libs/core/futures/src/future_data.cpp`:
- Around line 393-400: Update the lambda assigned to wait_cond in
future_data_base::wait_until by adding the explicit empty parameter list,
changing the capture form from [this] to [this](), so it remains compatible with
C++20.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e668afd1-f0dc-405a-9f88-f8edd7c77bc2
📒 Files selected for processing (10)
libs/core/execution_base/include/hpx/execution_base/agent_base.hpplibs/core/execution_base/include/hpx/execution_base/agent_ref.hpplibs/core/execution_base/src/agent_ref.cpplibs/core/execution_base/src/this_thread.cpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/src/future_data.cpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/threading_base/include/hpx/threading_base/execution_agent.hpplibs/core/threading_base/src/execution_agent.cpp
…de ready Signed-off-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>
131f15d to
42f4bd0
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/core/execution_base/include/hpx/execution_base/this_thread.hpp`:
- Around line 78-85: Update the default desc value in this_thread::sleep_until
to identify sleep_until rather than sleep_for, preserving the existing
agent().sleep_until call and diagnostics behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fdc8c829-1508-4707-95a7-d40b2ea453ad
📒 Files selected for processing (4)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/tests/unit/condition_variable.cpp
c1ad7b2 to
8201c2b
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
libs/core/synchronization/src/detail/condition_variable.cpp (1)
250-272: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNon-predicate
wait_untilduplicates the predicate overload; delegate instead.This body is identical to the predicate overload except for the always-false predicate. Delegating keeps the two in sync and is behavior-preserving: with an always-false predicate
sissignaledon notify (f.ctx_cleared) andtimeouton timer expiry (f.ctx_still set), yielding the same result as the currentf.ctx_ ? timeout : signaled.♻️ Proposed delegation
threads::thread_restart_state condition_variable::wait_until( std::unique_lock<mutex_type>& lock, hpx::chrono::steady_time_point const& abs_time, - char const* /* description */, error_code& /* ec */) - { - HPX_ASSERT_OWNS_LOCK(lock); - - // enqueue the request and block this thread - auto const this_ctx = hpx::execution_base::this_thread::agent(); - queue_entry f(this_ctx, &queue_); - queue_.push_back(f); - - reset_queue_entry r(f); - - { - // suspend this thread - unlock_guard<std::unique_lock<mutex_type>> ul(lock); - this_ctx.sleep_until(abs_time.value(), [] { return false; }); - } - - return f.ctx_ ? threads::thread_restart_state::timeout : - threads::thread_restart_state::signaled; - } + char const* description, error_code& ec) + { + return wait_until(lock, abs_time, + hpx::move_only_function<bool()>([] { return false; }), description, + ec); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/core/synchronization/src/detail/condition_variable.cpp` around lines 250 - 272, Refactor the non-predicate condition_variable::wait_until overload to delegate to the predicate-based wait_until overload using an always-false predicate, preserving its existing timeout/signaled behavior. Remove the duplicated queueing and sleep logic from this overload while forwarding the lock, abs_time, description, and error_code arguments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@libs/core/synchronization/src/detail/condition_variable.cpp`:
- Around line 250-272: Refactor the non-predicate condition_variable::wait_until
overload to delegate to the predicate-based wait_until overload using an
always-false predicate, preserving its existing timeout/signaled behavior.
Remove the duplicated queueing and sleep logic from this overload while
forwarding the lock, abs_time, description, and error_code arguments.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 94716dff-06a9-43d0-ade5-fa0ebd5703c0
📒 Files selected for processing (7)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/include/hpx/synchronization/condition_variable.hpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/synchronization/tests/unit/condition_variable.cpp
🚧 Files skipped from review as they are similar to previous changes (4)
- libs/core/execution_base/include/hpx/execution_base/this_thread.hpp
- libs/core/futures/tests/unit/future.cpp
- libs/core/execution_base/tests/unit/execution_context.cpp
- libs/core/synchronization/tests/unit/condition_variable.cpp
8201c2b to
7a913ea
Compare
Performance test reportHPX PerformanceComparison
Info
Comparison
Info
Comparison
Info
Explanation of Symbols
|
7a913ea to
fa8e4e3
Compare
Performance test reportHPX PerformanceComparison
Info
Comparison
Info
Comparison
Info
Explanation of Symbols
|
fa8e4e3 to
418bcae
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
libs/core/synchronization/src/detail/condition_variable.cpp (1)
276-300: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winReturn
signaledwhen the wait predicate ends the suspension.When
wait_condbecomes true,sleep_untilreportssignaled, butf.ctx_remains set because no notification removed the entry. Line 298 therefore incorrectly converts the predicate wake-up totimeout.Proposed restart-state mapping
- return f.ctx_ || s == threads::thread_restart_state::timeout ? + return s == threads::thread_restart_state::timeout ? threads::thread_restart_state::timeout : threads::thread_restart_state::signaled;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/core/synchronization/src/detail/condition_variable.cpp` around lines 276 - 300, Update condition_variable::wait_until so a sleep_until result of signaled is returned as signaled even when f.ctx_ remains set. Preserve timeout handling for an actual timeout, and keep notification-driven wake-ups mapped to the existing signaled behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@libs/core/synchronization/include/hpx/synchronization/condition_variable.hpp`:
- Around line 358-368: Update both predicate-based condition-variable wait
paths, including the overload around wait_until and the corresponding path near
the second occurrence, so user pred is evaluated while the caller’s lock remains
held. Do not forward pred through the lower predicate-aware
wait_until/sleep_until path after constructing unlock_guard; instead use the
non-predicate wait and recheck pred under the lock, while preserving the
existing inner-lock ordering and timeout behavior.
- Around line 436-440: Update the timed stop-token wait path around
wait_until_pred to forward the original predicate instead of passing the lvalue
copy. Ensure wait_until_pred and the subsequent wait layer preserve the same
predicate object, supporting move-only predicates and retaining state changes
from stateful predicates.
In `@libs/core/synchronization/src/detail/condition_variable.cpp`:
- Around line 250-274: The condition_variable::wait_until predicate must stop
polling the non-atomic queue_entry field f.ctx_ while the lock is released. Add
or reuse an atomic notification marker in queue_entry, set it before
notify_one/notify_all clear ctx_, and have the sleep_until predicate poll that
marker; update the final timeout/signaled decision to use the marker
consistently.
---
Outside diff comments:
In `@libs/core/synchronization/src/detail/condition_variable.cpp`:
- Around line 276-300: Update condition_variable::wait_until so a sleep_until
result of signaled is returned as signaled even when f.ctx_ remains set.
Preserve timeout handling for an actual timeout, and keep notification-driven
wake-ups mapped to the existing signaled behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 53282baf-6814-4f64-a633-a814d2113840
📒 Files selected for processing (7)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/include/hpx/synchronization/condition_variable.hpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/synchronization/tests/unit/condition_variable.cpp
🚧 Files skipped from review as they are similar to previous changes (5)
- libs/core/execution_base/include/hpx/execution_base/this_thread.hpp
- libs/core/execution_base/tests/unit/execution_context.cpp
- libs/core/futures/tests/unit/future.cpp
- libs/core/synchronization/tests/unit/condition_variable.cpp
- libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp
Performance test reportHPX PerformanceComparison
Info
Comparison
Info
Comparison
Info
Explanation of Symbols
|
418bcae to
17397ac
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
libs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp (1)
23-24: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueForward declaration's template parameter name diverges from the definition.
The forward declaration uses
Lockablewhile the actual definition at line 69 usesLock. Not a functional issue since parameter names in declarations are independent, but keeping them consistent aids readability.✏️ Suggested consistency fix
- HPX_CXX_CORE_EXPORT template <typename Lockable> + HPX_CXX_CORE_EXPORT template <typename Lock> class relock_guard;Also applies to: 69-70
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp` around lines 23 - 24, Align the template parameter name in the relock_guard forward declaration with its definition by changing Lockable to Lock, while leaving the class behavior and declaration structure unchanged.libs/core/synchronization/src/detail/condition_variable.cpp (1)
259-286: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueOptional: the no-predicate overload largely duplicates the predicate overload.
Both overloads differ only in the
sleep_untilpredicate and are otherwise identical (enqueue,reset_queue_entry, restart-state mapping). The no-predicate version is equivalent to delegating to the predicate overload with an always-false predicate. Consider consolidating to reduce drift between the two paths (weigh against the smallmove_only_functionallocation on this hot path).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/core/synchronization/src/detail/condition_variable.cpp` around lines 259 - 286, Consolidate the no-predicate condition_variable::wait_until implementation by delegating to the existing predicate overload with an always-false predicate, preserving the enqueue, reset, and restart-state behavior. Confirm this does not introduce an unacceptable move_only_function allocation on this hot path; if it does, retain the separate implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@libs/core/synchronization/src/detail/condition_variable.cpp`:
- Around line 259-286: Consolidate the no-predicate
condition_variable::wait_until implementation by delegating to the existing
predicate overload with an always-false predicate, preserving the enqueue,
reset, and restart-state behavior. Confirm this does not introduce an
unacceptable move_only_function allocation on this hot path; if it does, retain
the separate implementation.
In `@libs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp`:
- Around line 23-24: Align the template parameter name in the relock_guard
forward declaration with its definition by changing Lockable to Lock, while
leaving the class behavior and declaration structure unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7586e4a7-d6f9-401d-ba12-16c41dac8d8a
📒 Files selected for processing (8)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/include/hpx/synchronization/condition_variable.hpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/synchronization/tests/unit/condition_variable.cpplibs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp
🚧 Files skipped from review as they are similar to previous changes (6)
- libs/core/execution_base/include/hpx/execution_base/this_thread.hpp
- libs/core/synchronization/include/hpx/synchronization/condition_variable.hpp
- libs/core/synchronization/tests/unit/condition_variable.cpp
- libs/core/futures/tests/unit/future.cpp
- libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp
- libs/core/execution_base/tests/unit/execution_context.cpp
Performance test reportHPX PerformanceComparison
Info
Comparison
Info
Comparison
Info
Explanation of Symbols
|
d1e4604 to
10c7adb
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@libs/core/futures/tests/unit/future.cpp`:
- Around line 478-527: In test_wait_for_returns_as_soon_as_value_is_set and
test_wait_until_returns_as_soon_as_value_is_set, tighten the elapsed-time
assertions to use a short timeout and CI-tolerant bound appropriate for the
100-millisecond fulfillment, rather than allowing nearly five seconds. Apply the
same adjustment to the additional readiness timing test covering the indicated
range, while preserving the existing status and value assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 2683699c-79a1-4b6a-b3d4-d2fa3348bdc2
📒 Files selected for processing (8)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/include/hpx/synchronization/condition_variable.hpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/synchronization/tests/unit/condition_variable.cpplibs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp
🚧 Files skipped from review as they are similar to previous changes (7)
- libs/core/execution_base/include/hpx/execution_base/this_thread.hpp
- libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp
- libs/core/synchronization/include/hpx/synchronization/condition_variable.hpp
- libs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp
- libs/core/execution_base/tests/unit/execution_context.cpp
- libs/core/synchronization/tests/unit/condition_variable.cpp
- libs/core/synchronization/src/detail/condition_variable.cpp
10c7adb to
945f667
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp (1)
118-123: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider a default-description convenience overload for symmetry.
The plain
wait_untilgets a convenience overload with a default description (Lines 124-131), but this new predicate-taking overload has no equivalent — callers must always supplydescriptionexplicitly. Minor API asymmetry; worth a short overload if predicate-based callers elsewhere in the stack would benefit from a default description.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp` around lines 118 - 123, Add a convenience overload alongside the predicate-taking wait_until declaration that omits description and forwards to the existing overload with the established default description, preserving all other parameters and error_code behavior. Keep the current overload unchanged and mirror the nearby plain wait_until overload’s API pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In
`@libs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpp`:
- Around line 118-123: Add a convenience overload alongside the predicate-taking
wait_until declaration that omits description and forwards to the existing
overload with the established default description, preserving all other
parameters and error_code behavior. Keep the current overload unchanged and
mirror the nearby plain wait_until overload’s API pattern.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bbc9df83-87a0-4ed8-8622-9cf9e98018aa
📒 Files selected for processing (8)
libs/core/execution_base/include/hpx/execution_base/this_thread.hpplibs/core/execution_base/tests/unit/execution_context.cpplibs/core/futures/tests/unit/future.cpplibs/core/synchronization/include/hpx/synchronization/condition_variable.hpplibs/core/synchronization/include/hpx/synchronization/detail/condition_variable.hpplibs/core/synchronization/src/detail/condition_variable.cpplibs/core/synchronization/tests/unit/condition_variable.cpplibs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp
🚧 Files skipped from review as they are similar to previous changes (7)
- libs/core/execution_base/include/hpx/execution_base/this_thread.hpp
- libs/core/execution_base/tests/unit/execution_context.cpp
- libs/core/thread_support/include/hpx/thread_support/unlock_guard.hpp
- libs/core/synchronization/include/hpx/synchronization/condition_variable.hpp
- libs/core/synchronization/src/detail/condition_variable.cpp
- libs/core/futures/tests/unit/future.cpp
- libs/core/synchronization/tests/unit/condition_variable.cpp
945f667 to
de2cf58
Compare
Implemented from a Change Stack AI coding task. Co-authored-by: CodeRabbit <noreply@coderabbit.ai> Signed-off-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>
de2cf58 to
d478f99
Compare
Performance test reportHPX PerformanceComparison
Info
Comparison
Info
Comparison
Info
Explanation of Symbols
|
Future waits now stop promptly once the associated shared state transitions to ready.