summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpogorelov <[email protected]>2023-08-10 08:23:42 +0300
committerpogorelov <[email protected]>2023-08-10 09:13:07 +0300
commit3d2b9ca36aa6d1be0b792ebd485cc880f813f266 (patch)
tree2be1a6a8dbec8f1aeb981c4d6f287d04884fe756
parentd4ec755cea7534b856f580f608fc1c35d4a46b4e (diff)
Implement rvalue AsyncVia and Via for TExtendedCallback
-rw-r--r--yt/yt/core/actions/bind.h23
-rw-r--r--yt/yt/core/actions/future-inl.h32
-rw-r--r--yt/yt/core/actions/invoker-inl.h22
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))...));
});
}