Skip to content

Commit

Permalink
Added implicit futurization to async(client_base(), ...)
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed Apr 3, 2016
1 parent 98899c7 commit 72cf2f8
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 86 deletions.
2 changes: 1 addition & 1 deletion hpx/async.hpp
Expand Up @@ -103,7 +103,7 @@ namespace hpx { namespace detail
traits::detail::is_deferred_callable<F(Ts&&...)>::value,
hpx::future<typename util::detail::deferred_result_of<F(Ts&&...)>::type>
>::type
call(launch launch_policy, F&& f, Ts&&... ts)
call(launch launch_policy, F && f, Ts&&... ts)
{
typedef typename util::detail::deferred_result_of<
F(Ts&&...)
Expand Down
72 changes: 43 additions & 29 deletions hpx/lcos/async.hpp
Expand Up @@ -17,6 +17,7 @@
#include <hpx/runtime/launch_policy.hpp>
#include <hpx/runtime/naming/id_type.hpp>
#include <hpx/runtime/components/client_base.hpp>
#include <hpx/util/deferred_call.hpp>
#include <hpx/lcos/detail/async_implementations.hpp>
#include <hpx/lcos/future.hpp>
#include <hpx/lcos/async_fwd.hpp>
Expand All @@ -26,6 +27,27 @@
///////////////////////////////////////////////////////////////////////////////
namespace hpx { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <typename Action>
struct async_action_client_dispatch
{
template <typename Client, typename Stub, typename ...Ts>
HPX_FORCEINLINE lcos::future<
typename traits::promise_local_result<
typename traits::extract_action<
Action
>::remote_result_type
>::type>
operator()(launch launch_policy,
components::client_base<Client, Stub> const& c, Ts &&... ts) const
{
HPX_ASSERT(c.is_ready());
return hpx::detail::async_impl<Action>(launch_policy, c.get_id(),
std::forward<Ts>(ts)...);
}
};

///////////////////////////////////////////////////////////////////////////
// launch
template <typename Action, typename Policy>
struct async_action_dispatch<Action, Policy,
Expand All @@ -35,7 +57,8 @@ namespace hpx { namespace detail
{
// id_type
template <typename ...Ts>
HPX_FORCEINLINE static lcos::future<
HPX_FORCEINLINE static
lcos::future<
typename traits::promise_local_result<
typename hpx::actions::extract_action<
Action
Expand All @@ -48,7 +71,8 @@ namespace hpx { namespace detail
}

template <typename Client, typename Stub, typename ...Ts>
HPX_FORCEINLINE static lcos::future<
HPX_FORCEINLINE static
lcos::future<
typename traits::promise_local_result<
typename traits::extract_action<
Action
Expand All @@ -57,6 +81,7 @@ namespace hpx { namespace detail
call(launch launch_policy,
components::client_base<Client, Stub> const& c, Ts&&... ts)
{
// make sure the action is compatible with the component type
typedef typename components::client_base<
Client, Stub
>::server_component_type component_type;
Expand All @@ -65,8 +90,18 @@ namespace hpx { namespace detail
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return hpx::detail::async_impl<Action>(launch_policy, c.get_id(),
std::forward<Ts>(ts)...);
// invoke directly if client is ready
if (c.is_ready())
{
return hpx::detail::async_impl<Action>(
launch_policy, c.get_id(), std::forward<Ts>(ts)...);
}

// defer invocation otherwise
return c.then(util::deferred_call(
async_action_client_dispatch<Action>(),
launch_policy, c, std::forward<Ts>(ts)...
));
}

// distribution policy
Expand Down Expand Up @@ -127,17 +162,9 @@ namespace hpx { namespace detail
>::type>
call(components::client_base<Client_, Stub> const& c, Ts&&... ts)
{
typedef typename components::client_base<
Client_, Stub
>::server_component_type component_type;

typedef traits::is_valid_action<Action, component_type> is_valid;
static_assert(is_valid::value,
"The action to invoke is not supported by the target");

return async_action_dispatch<
Action, launch
>::call(launch::all, c.get_id(), std::forward<Ts>(ts)...);
>::call(launch::all, c, std::forward<Ts>(ts)...);
}
};

Expand Down Expand Up @@ -180,22 +207,9 @@ namespace hpx { namespace detail
template <typename ...Ts>
HPX_FORCEINLINE static
lcos::future<result_type>
call(launch launch_policy,
Action const&, naming::id_type const& id, Ts&&... ts)
{
return async<Action>(launch_policy, id, std::forward<Ts>(ts)...);
}

template <typename DistPolicy, typename ...Ts>
HPX_FORCEINLINE static
typename boost::enable_if_c<
traits::is_distribution_policy<DistPolicy>::value,
lcos::future<result_type>
>::type
call(launch launch_policy,
Action const&, DistPolicy const& policy, Ts&&... ts)
call(launch launch_policy, Action const&, Ts &&... ts)
{
return async<Action>(launch_policy, policy, std::forward<Ts>(ts)...);
return async<Action>(launch_policy, std::forward<Ts>(ts)...);
}
};
}}
Expand Down Expand Up @@ -290,7 +304,7 @@ namespace hpx { namespace detail
{
template <typename F, typename ...Ts>
HPX_FORCEINLINE static auto
call(launch const& launch_policy, F&& f, Ts&&... ts)
call(launch const& launch_policy, F && f, Ts &&... ts)
-> decltype(detail::async_launch_policy_dispatch<
typename util::decay<F>::type
>::call(launch_policy, std::forward<F>(f), std::forward<Ts>(ts)...))
Expand Down
113 changes: 57 additions & 56 deletions hpx/runtime/components/client_base.hpp
Expand Up @@ -362,20 +362,6 @@ namespace hpx { namespace components
}
#endif

id_type const& get() const
{
if (!shared_state_)
{
HPX_THROW_EXCEPTION(no_state,
"client_base::get_gid",
"this client_base has no valid shared state");
}

// no error has been reported, return the result
return lcos::detail::future_value<id_type>::
get(*shared_state_->get_result());
}

id_type const& get_id() const
{
return get();
Expand Down Expand Up @@ -415,8 +401,23 @@ namespace hpx { namespace components
*this = std::move(rhs);
}

public:
///////////////////////////////////////////////////////////////////////
// Interface mimicking future
// Exposition only: interface mimicking future

id_type const& get() const
{
if (!shared_state_)
{
HPX_THROW_EXCEPTION(no_state,
"client_base::get_gid",
"this client_base has no valid shared state");
}

// no error has been reported, return the result
return lcos::detail::future_value<id_type>::
get(*shared_state_->get_result());
}

// Returns: true if the shared state is ready, false if it isn't.
bool is_ready() const HPX_NOEXCEPT
Expand Down Expand Up @@ -469,8 +470,48 @@ namespace hpx { namespace components
return hpx::detail::access_exception(ec);
}

private:
template <typename F>
static typename lcos::detail::future_then_result<Derived, F>::cont_result
on_ready(shared_future<id_type> && fut, F f)
{
return f(Derived(std::move(fut)));
}

public:
template <typename F>
typename lcos::detail::future_then_result<Derived, F>::type
then(F && f)
{
typedef
typename lcos::detail::future_then_result<Derived, F>::result_type
result_type;

if (!shared_state_)
{
HPX_THROW_EXCEPTION(no_state,
"client_base::then",
"this client_base has no valid shared state");
return future<result_type>();
}

typedef
typename hpx::util::result_of<F(Derived)>::type
continuation_result_type;
typedef
typename hpx::traits::detail::shared_state_ptr<result_type>::type
shared_state_ptr;

shared_state_ptr p =
lcos::detail::make_continuation<continuation_result_type>(
*static_cast<Derived const*>(this), launch::all,
std::forward<F>(f));
return hpx::traits::future_access<future<result_type> >::create(
std::move(p));
}

private:
///////////////////////////////////////////////////////////////////////
protected:
static void register_as_helper(Derived && f,
std::string const& symbolic_name)
{
Expand Down Expand Up @@ -519,46 +560,6 @@ namespace hpx { namespace components
registered_name_.clear();
}

protected:
template <typename F>
static typename lcos::detail::future_then_result<Derived, F>::cont_result
on_ready(shared_future<id_type> && fut, F f)
{
return f(Derived(std::move(fut)));
}

public:
template <typename F>
typename lcos::detail::future_then_result<Derived, F>::type
then(F && f)
{
typedef
typename lcos::detail::future_then_result<Derived, F>::result_type
result_type;

if (!shared_state_)
{
HPX_THROW_EXCEPTION(no_state,
"client_base::then",
"this client_base has no valid shared state");
return future<result_type>();
}

typedef
typename hpx::util::result_of<F(Derived)>::type
continuation_result_type;
typedef
typename hpx::traits::detail::shared_state_ptr<result_type>::type
shared_state_ptr;

shared_state_ptr p =
lcos::detail::make_continuation<continuation_result_type>(
*static_cast<Derived const*>(this), launch::all,
std::forward<F>(f));
return hpx::traits::future_access<future<result_type> >::create(
std::move(p));
}

protected:
// will be set for created (non-attached) objects
std::string registered_name_;
Expand Down

0 comments on commit 72cf2f8

Please sign in to comment.