From 9cbe23d8f01ea5508fc78dae599bc4b0bff3bed2 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Thu, 27 Jun 2024 09:35:53 -0500 Subject: [PATCH] Trying to fix segfault in examples --- .../hpx/futures/detail/future_data.hpp | 4 ++-- .../include/hpx/futures/futures_factory.hpp | 2 +- .../hpx/futures/packaged_continuation.hpp | 20 ++++++++----------- libs/core/futures/src/future_data.cpp | 10 ++++------ .../include/hpx/components/client_base.hpp | 5 ++--- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/libs/core/futures/include/hpx/futures/detail/future_data.hpp b/libs/core/futures/include/hpx/futures/detail/future_data.hpp index 2f108651a6d1..1839709b0904 100644 --- a/libs/core/futures/include/hpx/futures/detail/future_data.hpp +++ b/libs/core/futures/include/hpx/futures/detail/future_data.hpp @@ -99,7 +99,7 @@ namespace hpx::lcos::detail { virtual ~future_data_refcnt_base(); - virtual void set_on_completed(completed_callback_type) = 0; + virtual void set_on_completed(completed_callback_type&&) = 0; HPX_FORCEINLINE bool requires_delete() noexcept { @@ -313,7 +313,7 @@ namespace hpx::lcos::detail { // Set the callback which needs to be invoked when the future becomes // ready. If the future is ready the function will be invoked // immediately. - void set_on_completed(completed_callback_type data_sink) override; + void set_on_completed(completed_callback_type&& data_sink) override; virtual state wait(error_code& ec = throws); diff --git a/libs/core/futures/include/hpx/futures/futures_factory.hpp b/libs/core/futures/include/hpx/futures/futures_factory.hpp index 6ab780cdaa60..ac412045a4ee 100644 --- a/libs/core/futures/include/hpx/futures/futures_factory.hpp +++ b/libs/core/futures/include/hpx/futures/futures_factory.hpp @@ -50,7 +50,7 @@ namespace hpx::lcos::local { using result_type = typename Base::result_type; using init_no_addref = typename Base::init_no_addref; - F f_; + std::decay_t f_; explicit task_object(F const& f) : f_(f) diff --git a/libs/core/futures/include/hpx/futures/packaged_continuation.hpp b/libs/core/futures/include/hpx/futures/packaged_continuation.hpp index c7c38d936d43..f337114d1d23 100644 --- a/libs/core/futures/include/hpx/futures/packaged_continuation.hpp +++ b/libs/core/futures/include/hpx/futures/packaged_continuation.hpp @@ -36,7 +36,7 @@ namespace hpx::lcos::detail { template HPX_FORCEINLINE void transfer_result( - SourceState&& src, DestinationState const& dest) + SourceState&& src, DestinationState& dest) { hpx::detail::try_catch_exception_ptr( [&]() { @@ -88,6 +88,8 @@ namespace hpx::lcos::detail { } else { + hpx::intrusive_ptr cont_(&cont); + hpx::detail::try_catch_exception_ptr( [&]() { using inner_shared_state_ptr = @@ -109,13 +111,12 @@ namespace hpx::lcos::detail { // Bind an on_completed handler to this future that will // transfer its result to the new future. - hpx::intrusive_ptr cont_(&cont); ptr->execute_deferred(); ptr->set_on_completed( [inner_state = HPX_MOVE(inner_state), cont_ = HPX_MOVE(cont_)]() mutable -> void { return transfer_result( - HPX_MOVE(inner_state), HPX_MOVE(cont_)); + HPX_MOVE(inner_state), cont_); }); }, [&](std::exception_ptr ep) { @@ -404,13 +405,6 @@ namespace hpx::lcos::detail { class unwrap_continuation : public future_data { private: - template - void on_inner_ready( - traits::detail::shared_state_ptr_for_t&& inner_state) - { - transfer_result(HPX_MOVE(inner_state), this); - } - template void on_outer_ready( traits::detail::shared_state_ptr_for_t&& outer_state) @@ -443,11 +437,13 @@ namespace hpx::lcos::detail { } ptr->execute_deferred(); + + // attach continuation on inner ready ptr->set_on_completed( [this_ = HPX_MOVE(this_), inner = HPX_MOVE(inner_state)]() mutable -> void { - this_->template on_inner_ready( - HPX_MOVE(inner)); + transfer_result( + HPX_MOVE(inner), this_); }); }, [&](std::exception_ptr ep) { diff --git a/libs/core/futures/src/future_data.cpp b/libs/core/futures/src/future_data.cpp index e41a4e4d5844..f0002a6f807c 100644 --- a/libs/core/futures/src/future_data.cpp +++ b/libs/core/futures/src/future_data.cpp @@ -101,8 +101,7 @@ namespace hpx::lcos::detail { { if (runs_child_ != threads::invalid_thread_id) { - auto* thrd = get_thread_id_data(runs_child_); - (void) thrd; + [[maybe_unused]] auto* thrd = get_thread_id_data(runs_child_); LTM_(debug).format( "task_object::~task_object({}), description({}): " "destroy runs_as_child thread", @@ -284,7 +283,7 @@ namespace hpx::lcos::detail { hpx::detail::try_catch_exception_ptr( [&]() { // clang-format off - constexpr void (*p)(Callback&&) noexcept = + constexpr void (*p)(std::decay_t&&) noexcept = &future_data_base::run_on_completed; // clang-format on run_on_completed_on_new_thread(util::deferred_call( @@ -318,11 +317,12 @@ namespace hpx::lcos::detail { // Set the callback which needs to be invoked when the future becomes ready. // If the future is ready the function will be invoked immediately. void future_data_base::set_on_completed( - completed_callback_type data_sink) + completed_callback_type&& data_sink) { if (!data_sink) return; + hpx::intrusive_ptr this_(this); // keep alive if (is_ready(std::memory_order_relaxed)) { // invoke the callback (continuation) function right away @@ -330,8 +330,6 @@ namespace hpx::lcos::detail { } else { - hpx::intrusive_ptr this_(this); // keep alive - std::unique_lock l(mtx_); if (is_ready()) { diff --git a/libs/full/components/include/hpx/components/client_base.hpp b/libs/full/components/include/hpx/components/client_base.hpp index 1d3117f00d86..2656e6a19d52 100644 --- a/libs/full/components/include/hpx/components/client_base.hpp +++ b/libs/full/components/include/hpx/components/client_base.hpp @@ -335,9 +335,8 @@ namespace hpx::components { { } explicit client_base(hpx::future&& f) noexcept - : shared_state_( - hpx::traits::future_access::get_shared_state( - HPX_MOVE(f))) + : shared_state_(hpx::traits::future_access< + hpx::future>::get_shared_state(HPX_MOVE(f))) { }