Skip to content

make_future: take run_loop& directly, removing the __loop_ access entirely#7248

Open
guptapratykshh wants to merge 9 commits intoTheHPXProject:masterfrom
guptapratykshh:feat/make_future-take-run-loop-directly
Open

make_future: take run_loop& directly, removing the __loop_ access entirely#7248
guptapratykshh wants to merge 9 commits intoTheHPXProject:masterfrom
guptapratykshh:feat/make_future-take-run-loop-directly

Conversation

@guptapratykshh
Copy link
Copy Markdown
Contributor

Proposed Changes

  • Change hpx::execution::experimental::make_future to accept a run_loop& directly instead of recovering it from a run_loop::scheduler. The tag_invoke(make_future_t, ...) overload now takes run_loop& as its first argument; a new tag_fallback_invoke overload makes make_future(loop) pipe-able with a sender via a small inject_run_loop partial-algorithm adapter (sibling of the existing inject_scheduler).
  • Delete the detail::get_run_loop_from_scheduler helper introduced in make_future: isolate __loop_ private-member access in single detail helper #7247 — it's no longer needed since the loop is now passed explicitly.
  • Update the algorithm_run_loop unit test's three make_future(sched, ...) callsites to make_future(loop, ...).

Any background context you want to provide?

Checklist

Not all points below apply to all pull requests.

  • I have added a new feature and have added tests to go along with it.
  • I have fixed a bug and have added a regression test.
  • I have added a test using random numbers; I have made sure it uses a seed, and that random numbers generated are valid inputs for the tests.

@guptapratykshh guptapratykshh requested a review from hkaiser as a code owner May 5, 2026 17:19
Copilot AI review requested due to automatic review settings May 5, 2026 17:19
@StellarBot
Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 5, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Refactors hpx::execution::experimental::make_future so the run-loop-backed path takes an explicit run_loop& instead of recovering the loop from a run_loop::scheduler, simplifying the implementation around sender-to-future bridging in the execution layer.

Changes:

  • Replaces the scheduler-based run-loop extraction path in make_future with direct run_loop& plumbing.
  • Adds a dedicated inject_run_loop partial adapter so make_future(loop) can still be used in pipe form.
  • Updates run-loop unit tests from make_future(sched, ...) to make_future(loop, ...).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
libs/core/execution/include/hpx/execution/algorithms/make_future.hpp Reworks make_future overloads and shared-state construction to take run_loop& directly.
libs/core/execution/include/hpx/execution/algorithms/detail/inject_scheduler.hpp Adds the new inject_run_loop partial adapter used by make_future(loop).
libs/core/execution/tests/unit/algorithm_run_loop.cpp Updates run-loop make_future call sites and adds basic pipe-form coverage for the new loop overload.

Comment on lines +353 to +357
hpx::execution::experimental::run_loop& loop, Sender&& sender,
Allocator const& allocator = Allocator{})
{
return detail::make_future_with_run_loop(
sched, HPX_FORWARD(Sender, sender), allocator);
loop, HPX_FORWARD(Sender, sender), allocator);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@guptapratykshh does this comment make sense?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i removed the scheduler-based binary tag_invoke overload, the tag_override_invoke constraint is_completion_scheduler_tag_invocable_v<set_value_t, Sender, make_future_t, Allocator> evaluates to false for run-loop-backed senders, so make_future(transfer_just(sched, ...)) falls to detail::make_future which never drives the loop → hang.

Comment on lines +400 to +405
friend constexpr HPX_FORCEINLINE auto tag_fallback_invoke(make_future_t,
hpx::execution::experimental::run_loop& loop,
Allocator const& allocator = Allocator{})
{
return hpx::execution::experimental::detail::inject_run_loop<
make_future_t, Allocator>{loop, allocator};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about this comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

inject_scheduler partial was returned by make_future(scheduler) but had nothing to dispatch to (no binary tag_invoke(make_future_t, scheduler, sender, alloc) overload exists for any scheduler type after this PR: there only ever was one for run_loop::scheduler, which was replaced)

[[maybe_unused]] auto sched = loop.get_scheduler();

auto f = ex::just(3) | ex::make_future(sched);
auto f = ex::just(3) | ex::make_future(loop);
@guptapratykshh
Copy link
Copy Markdown
Contributor Author

@hkaiser cmake -G "Visual Studio 17 2022" is failing with "could not find any instance of Visual Studio" on the Windows runner. Affects windows_release_2022.yml and windows_clang_release.yml.

@hkaiser hkaiser added type: enhancement type: compatibility issue category: senders/receivers Implementations of the p0443r14 / p2300 + p1897 proposals labels May 5, 2026
Comment on lines +353 to +357
hpx::execution::experimental::run_loop& loop, Sender&& sender,
Allocator const& allocator = Allocator{})
{
return detail::make_future_with_run_loop(
sched, HPX_FORWARD(Sender, sender), allocator);
loop, HPX_FORWARD(Sender, sender), allocator);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@guptapratykshh does this comment make sense?

Comment on lines +400 to +405
friend constexpr HPX_FORCEINLINE auto tag_fallback_invoke(make_future_t,
hpx::execution::experimental::run_loop& loop,
Allocator const& allocator = Allocator{})
{
return hpx::execution::experimental::detail::inject_run_loop<
make_future_t, Allocator>{loop, allocator};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about this comment?

// was removed when the `make_future` API moved to taking `run_loop&`
// explicitly: there was no longer any binary
// `tag_invoke(Tag, scheduler, sender, alloc)` overload for the partial
// to dispatch to.)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should leave the old inject_scheduler in place as it may be used in other places. The inject_run_loop could be simply added on top of the existing functionalities.

Copilot AI review requested due to automatic review settings May 5, 2026 20:01
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

Comment on lines 352 to +357
friend auto tag_invoke(make_future_t,
decltype(std::declval<hpx::execution::experimental::run_loop>()
.get_scheduler()) const& sched,
Sender&& sender, Allocator const& allocator = Allocator{})
hpx::execution::experimental::run_loop& loop, Sender&& sender,
Allocator const& allocator = Allocator{})
{
return detail::make_future_with_run_loop(
sched, HPX_FORWARD(Sender, sender), allocator);
loop, HPX_FORWARD(Sender, sender), allocator);
Comment on lines +400 to +405
friend constexpr HPX_FORCEINLINE auto tag_fallback_invoke(make_future_t,
hpx::execution::experimental::run_loop& loop,
Allocator const& allocator = Allocator{})
{
return hpx::execution::experimental::detail::inject_run_loop<
make_future_t, Allocator>{loop, allocator};
[[maybe_unused]] auto sched = loop.get_scheduler();

auto f = ex::transfer_just(sched, 3) | ex::make_future();
auto f = ex::transfer_just(sched, 3) | ex::make_future(loop);
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 5, 2026

@hkaiser cmake -G "Visual Studio 17 2022" is failing with "could not find any instance of Visual Studio" on the Windows runner. Affects windows_release_2022.yml and windows_clang_release.yml.

Please rebase onto master, this has been fixed there.

Copilot AI review requested due to automatic review settings May 6, 2026 09:02
@guptapratykshh guptapratykshh force-pushed the feat/make_future-take-run-loop-directly branch from d9f4481 to 1fc1401 Compare May 6, 2026 09:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

@@ -421,6 +387,24 @@ namespace hpx::execution::experimental {
HPX_FORWARD(Scheduler, scheduler), allocator};
}

Comment on lines +62 to +76
// Sibling of `inject_scheduler` that holds a reference to a `run_loop`
// instead of a scheduler. Used so that `make_future(loop)` yields a
// pipe-able adapter which, when piped with a sender, dispatches
// `tag_invoke(Tag, run_loop&, sender, ...)`.
HPX_CXX_CORE_EXPORT template <typename Tag, typename... Ts>
struct inject_run_loop
: partial_algorithm_base<Tag, hpx::util::make_index_pack_t<sizeof...(Ts)>,
Ts...>
{
private:
// Stored as a pointer because the partial may be moved and references
// can't be re-bound; the `run_loop&` lifetime is the caller's
// responsibility (the same as the `scheduler` case).
hpx::execution::experimental::run_loop* loop_;

…ll site, add explicit run_loop include in inject_scheduler.hpp
Copilot AI review requested due to automatic review settings May 6, 2026 09:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment on lines +403 to +415
friend constexpr auto tag_fallback_invoke(make_future_t,
typename hpx::execution::experimental::run_loop::scheduler const&) =
delete;

// clang-format off
template <typename Allocator,
HPX_CONCEPT_REQUIRES_(
hpx::traits::is_allocator_v<Allocator>
)>
// clang-format on
friend constexpr auto tag_fallback_invoke(make_future_t,
typename hpx::execution::experimental::run_loop::scheduler const&,
Allocator const&) = delete;
friend constexpr HPX_FORCEINLINE auto operator|(
U&& u, inject_run_loop p)
{
return HPX_MOVE(p).invoke(*p.loop_, HPX_FORWARD(U, u));
…aulted template args reject = delete on friends)
…, add NOLINT for use-after-move in inject_run_loop
Copilot AI review requested due to automatic review settings May 6, 2026 10:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment on lines 346 to 355
template <typename Sender,
typename Allocator = hpx::util::internal_allocator<>,
HPX_CONCEPT_REQUIRES_(
hpx::execution::experimental::is_sender_v<Sender>
)>
// clang-format on
friend auto tag_invoke(make_future_t,
decltype(std::declval<hpx::execution::experimental::run_loop>()
.get_scheduler()) const& sched,
Sender&& sender, Allocator const& allocator = Allocator{})
hpx::execution::experimental::run_loop& loop, Sender&& sender,
Allocator const& allocator = Allocator{})
{
Comment on lines +390 to +398
// `make_future(loop.get_scheduler())` is intentionally rejected at
// the call site: the run-loop-backed binary
// `tag_invoke(make_future_t, run_loop::scheduler, sender, alloc)`
// overload is gone (replaced by the `run_loop&` overload above).
// Without these deletes, the generic scheduler partial above would
// accept the call, return an `inject_scheduler`, and fail with a
// confusing substitution error only when the partial is later piped
// with a sender. Use `make_future(loop, sender)` /
// `sender | make_future(loop)` instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: senders/receivers Implementations of the p0443r14 / p2300 + p1897 proposals type: compatibility issue type: enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants