diff options
author | pogorelov <[email protected]> | 2023-08-10 08:23:42 +0300 |
---|---|---|
committer | pogorelov <[email protected]> | 2023-08-10 09:13:07 +0300 |
commit | 3d2b9ca36aa6d1be0b792ebd485cc880f813f266 (patch) | |
tree | 2be1a6a8dbec8f1aeb981c4d6f287d04884fe756 | |
parent | d4ec755cea7534b856f580f608fc1c35d4a46b4e (diff) |
Implement rvalue AsyncVia and Via for TExtendedCallback
-rw-r--r-- | yt/yt/core/actions/bind.h | 23 | ||||
-rw-r--r-- | yt/yt/core/actions/future-inl.h | 32 | ||||
-rw-r--r-- | yt/yt/core/actions/invoker-inl.h | 22 |
3 files changed, 60 insertions, 17 deletions
diff --git a/yt/yt/core/actions/bind.h b/yt/yt/core/actions/bind.h index 5c4ec018a64..d86078578c5 100644 --- a/yt/yt/core/actions/bind.h +++ b/yt/yt/core/actions/bind.h @@ -150,12 +150,13 @@ struct TFutureTraits<TFuture<T>> template <class TSignature> -struct TExtendedCallback; +class TExtendedCallback; template <class TR, class... TAs> -struct TExtendedCallback<TR(TAs...)> +class TExtendedCallback<TR(TAs...)> : public TCallback<TR(TAs...)> { +public: using TCallback<TR(TAs...)>::TCallback; TExtendedCallback(const TCallback<TR(TAs...)>& callback) @@ -165,11 +166,15 @@ struct TExtendedCallback<TR(TAs...)> using TCallback<TR(TAs...)>::operator ==; using TCallback<TR(TAs...)>::operator !=; #endif - // TODO: Make && - TExtendedCallback Via(TIntrusivePtr<IInvoker> invoker) const; + + TExtendedCallback Via(TIntrusivePtr<IInvoker> invoker) const &; + TExtendedCallback Via(TIntrusivePtr<IInvoker> invoker) &&; + + TExtendedCallback<typename TFutureTraits<TR>::TWrapped(TAs...)> + AsyncVia(TIntrusivePtr<IInvoker> invoker) const &; TExtendedCallback<typename TFutureTraits<TR>::TWrapped(TAs...)> - AsyncVia(TIntrusivePtr<IInvoker> invoker) const; + AsyncVia(TIntrusivePtr<IInvoker> invoker) &&; //! This version of AsyncVia is designed for cases when invoker may discard submitted callbacks //! (for example, if it is cancellable invoker). Regular AsyncVia results in "Promise abandoned" @@ -177,7 +182,13 @@ struct TExtendedCallback<TR(TAs...)> //! allows you to specify the cancellation error, which costs a bit more allocations //! but much more convenient. TExtendedCallback<typename TFutureTraits<TR>::TWrapped(TAs...)> - AsyncViaGuarded(TIntrusivePtr<IInvoker> invoker, TError cancellationError) const; + AsyncViaGuarded(TIntrusivePtr<IInvoker> invoker, TError cancellationError) const &; + + TExtendedCallback<typename TFutureTraits<TR>::TWrapped(TAs...)> + AsyncViaGuarded(TIntrusivePtr<IInvoker> invoker, TError cancellationError) &&; + +private: + static TExtendedCallback ViaImpl(TExtendedCallback callback, TIntrusivePtr<IInvoker> invoker); }; //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/actions/future-inl.h b/yt/yt/core/actions/future-inl.h index ff42d408f84..0b158ecf4bd 100644 --- a/yt/yt/core/actions/future-inl.h +++ b/yt/yt/core/actions/future-inl.h @@ -1577,21 +1577,21 @@ struct TAsyncViaHelper<R(TArgs...)> } static TFuture<TUnderlying> Outer( - const TSourceCallback& this_, + TSourceCallback this_, const IInvokerPtr& invoker, TArgs... args) { auto promise = NewPromise<TUnderlying>(); invoker->Invoke(BIND_NO_PROPAGATE( &Inner, - this_, + std::move(this_), promise, WrapToPassed(std::forward<TArgs>(args))...)); return promise; } static TFuture<TUnderlying> OuterGuarded( - const TSourceCallback& this_, + TSourceCallback this_, const IInvokerPtr& invoker, NYT::TError cancellationError, TArgs... args) @@ -1599,7 +1599,7 @@ struct TAsyncViaHelper<R(TArgs...)> auto promise = NewPromise<TUnderlying>(); GuardedInvoke( invoker, - BIND_NO_PROPAGATE(&Inner, this_, promise, WrapToPassed(std::forward<TArgs>(args))...), + BIND_NO_PROPAGATE(&Inner, std::move(this_), promise, WrapToPassed(std::forward<TArgs>(args))...), BIND_NO_PROPAGATE([promise, cancellationError = std::move(cancellationError)] { promise.Set(std::move(cancellationError)); })); @@ -1618,7 +1618,11 @@ struct TAsyncViaHelper<R(TArgs...)> IInvokerPtr invoker, NYT::TError cancellationError) { - return BIND_NO_PROPAGATE(&OuterGuarded, std::move(this_), std::move(invoker), std::move(cancellationError)); + return BIND_NO_PROPAGATE( + &OuterGuarded, + std::move(this_), + std::move(invoker), + std::move(cancellationError)); } }; @@ -1626,18 +1630,32 @@ struct TAsyncViaHelper<R(TArgs...)> template <class R, class... TArgs> TExtendedCallback<typename TFutureTraits<R>::TWrapped(TArgs...)> -TExtendedCallback<R(TArgs...)>::AsyncVia(IInvokerPtr invoker) const +TExtendedCallback<R(TArgs...)>::AsyncVia(IInvokerPtr invoker) const & { return NYT::NDetail::TAsyncViaHelper<R(TArgs...)>::Do(*this, std::move(invoker)); } template <class R, class... TArgs> TExtendedCallback<typename TFutureTraits<R>::TWrapped(TArgs...)> -TExtendedCallback<R(TArgs...)>::AsyncViaGuarded(IInvokerPtr invoker, NYT::TError cancellationError) const +TExtendedCallback<R(TArgs...)>::AsyncVia(IInvokerPtr invoker) && +{ + return NYT::NDetail::TAsyncViaHelper<R(TArgs...)>::Do(std::move(*this), std::move(invoker)); +} + +template <class R, class... TArgs> +TExtendedCallback<typename TFutureTraits<R>::TWrapped(TArgs...)> +TExtendedCallback<R(TArgs...)>::AsyncViaGuarded(IInvokerPtr invoker, NYT::TError cancellationError) const & { return NYT::NDetail::TAsyncViaHelper<R(TArgs...)>::DoGuarded(*this, std::move(invoker), std::move(cancellationError)); } +template <class R, class... TArgs> +TExtendedCallback<typename TFutureTraits<R>::TWrapped(TArgs...)> +TExtendedCallback<R(TArgs...)>::AsyncViaGuarded(IInvokerPtr invoker, NYT::TError cancellationError) && +{ + return NYT::NDetail::TAsyncViaHelper<R(TArgs...)>::DoGuarded(std::move(*this), std::move(invoker), std::move(cancellationError)); +} + //////////////////////////////////////////////////////////////////////////////// template <class T> diff --git a/yt/yt/core/actions/invoker-inl.h b/yt/yt/core/actions/invoker-inl.h index 4abd399de7c..34bea2bf4e9 100644 --- a/yt/yt/core/actions/invoker-inl.h +++ b/yt/yt/core/actions/invoker-inl.h @@ -11,16 +11,30 @@ namespace NYT { template <class R, class... TArgs> TExtendedCallback<R(TArgs...)> -TExtendedCallback<R(TArgs...)>::Via(IInvokerPtr invoker) const +TExtendedCallback<R(TArgs...)>::Via(IInvokerPtr invoker) const & +{ + return ViaImpl(*this, std::move(invoker)); +} + +template <class R, class... TArgs> +TExtendedCallback<R(TArgs...)> +TExtendedCallback<R(TArgs...)>::Via(IInvokerPtr invoker) && +{ + return ViaImpl(std::move(*this), std::move(invoker)); +} + + +template <class R, class... TArgs> +TExtendedCallback<R(TArgs...)> +TExtendedCallback<R(TArgs...)>::ViaImpl(TExtendedCallback<R(TArgs...)> callback, TIntrusivePtr<IInvoker> invoker) { static_assert( std::is_void_v<R>, "Via() can only be used with void return type."); YT_ASSERT(invoker); - auto this_ = *this; - return BIND_NO_PROPAGATE([=, invoker = std::move(invoker)] (TArgs... args) { - invoker->Invoke(BIND_NO_PROPAGATE(this_, WrapToPassed(std::forward<TArgs>(args))...)); + return BIND_NO_PROPAGATE([callback = std::move(callback), invoker = std::move(invoker)] (TArgs... args) { + invoker->Invoke(BIND_NO_PROPAGATE(callback, WrapToPassed(std::forward<TArgs>(args))...)); }); } |