summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarkady-e1ppa <[email protected]>2024-12-17 18:55:00 +0300
committerarkady-e1ppa <[email protected]>2024-12-17 19:15:57 +0300
commit174f410da8f66e7525c017656f485eb45a978a09 (patch)
tree847704b1c5cf78425dae037e6cac45005e70cb62
parent3474e0dbe58ae22cfd6d8784f476dbf816a1524d (diff)
Use AnyObject to remove type erasure logic from yt/yt/core
commit_hash:79b0a0b437e41879c3a7d4c079ab571bbaafd45f
-rw-r--r--library/cpp/yt/memory/type_erasure.h4
-rw-r--r--library/cpp/yt/memory/type_erasure_detail.h14
-rw-r--r--library/cpp/yt/memory/unittests/type_erasure_ut.cpp8
-rw-r--r--yt/yt/core/actions/cancelable_context.cpp4
-rw-r--r--yt/yt/core/actions/cancelation_token-inl.h142
-rw-r--r--yt/yt/core/actions/cancelation_token.cpp191
-rw-r--r--yt/yt/core/actions/cancelation_token.h129
-rw-r--r--yt/yt/core/actions/future-inl.h4
-rw-r--r--yt/yt/core/actions/unittests/cancelation_token_ut.cpp25
9 files changed, 104 insertions, 417 deletions
diff --git a/library/cpp/yt/memory/type_erasure.h b/library/cpp/yt/memory/type_erasure.h
index 92c4eb34c54..4c4afaecb26 100644
--- a/library/cpp/yt/memory/type_erasure.h
+++ b/library/cpp/yt/memory/type_erasure.h
@@ -218,7 +218,7 @@ public:
auto* mover = GetVTable().template GetFunctor<Mover<TStorage>>();
mover(std::move(other).GetStorage(), GetStorage());
- other.Holder_.Reset();
+ other.Reset();
}
}
@@ -236,7 +236,7 @@ public:
auto* mover = GetVTable().template GetFunctor<Mover<TStorage>>();
mover(std::move(other).GetStorage(), GetStorage());
- other.Holder_.Reset();
+ other.Reset();
}
return *this;
diff --git a/library/cpp/yt/memory/type_erasure_detail.h b/library/cpp/yt/memory/type_erasure_detail.h
index 5e158d3a814..3de22b8e0d0 100644
--- a/library/cpp/yt/memory/type_erasure_detail.h
+++ b/library/cpp/yt/memory/type_erasure_detail.h
@@ -369,11 +369,19 @@ private:
////////////////////////////////////////////////////////////////////////////////
template <class T, class TStorage>
+struct TIsVTable
+ : public std::false_type
+{ };
+
+template <CStorage TStorage, class... TCpos>
+struct TIsVTable<TVTable<TStorage, TCpos...>, TStorage>
+ : public std::true_type
+{ };
+
+template <class T, class TStorage>
concept CVTableFor =
CStorage<TStorage> &&
- requires (const T& t) {
- [] <class... TCpos> (TVTable<TStorage, TCpos...>) { } (t);
- };
+ TIsVTable<std::remove_cvref_t<T>, TStorage>::value;
////////////////////////////////////////////////////////////////////////////////
diff --git a/library/cpp/yt/memory/unittests/type_erasure_ut.cpp b/library/cpp/yt/memory/unittests/type_erasure_ut.cpp
index e6e917d9756..5c91d654bfd 100644
--- a/library/cpp/yt/memory/unittests/type_erasure_ut.cpp
+++ b/library/cpp/yt/memory/unittests/type_erasure_ut.cpp
@@ -292,7 +292,10 @@ TEST(TAnyObjectTest, CvRefCorrectness)
EXPECT_EQ(TestCpo(movedOut).Val, 11);
}
- EXPECT_EQ(cust.DtorCount, 5);
+ // NB(arkady-e1ppa): Moved out any should be
+ // actually empty thus moving out both moves object out
+ // and destroys the moved out object.
+ EXPECT_EQ(cust.DtorCount, 6);
EXPECT_THROW(any.AnyCast<TCustomized2>(), NDetail::TBadAnyCast);
}
@@ -316,7 +319,8 @@ TEST(TAnyObjectTest, StaticVTableForAnyRef)
EXPECT_EQ(TestCpo(movedOut).Val, 11);
}
EXPECT_EQ(cst.Value, 1111);
- EXPECT_EQ(cst.DtorCount, 2);
+ // NB(arkady-e1ppa): See comment in previous test.
+ EXPECT_EQ(cst.DtorCount, 3);
EXPECT_FALSE(any.IsValid());
}
diff --git a/yt/yt/core/actions/cancelable_context.cpp b/yt/yt/core/actions/cancelable_context.cpp
index 9993b14cf40..409954de738 100644
--- a/yt/yt/core/actions/cancelable_context.cpp
+++ b/yt/yt/core/actions/cancelable_context.cpp
@@ -26,7 +26,7 @@ public:
{
YT_ASSERT(callback);
- auto guard = NDetail::MakeCancelableContextCurrentTokenGuard(Context_);
+ auto currentTokenGuard = NDetail::MakeCancelableContextCurrentTokenGuard(Context_);
if (Context_->Canceled_) {
callback.Reset();
@@ -53,7 +53,7 @@ public:
void Invoke(TMutableRange<TClosure> callbacks) override
{
- auto guard = NDetail::MakeCancelableContextCurrentTokenGuard(Context_);
+ auto currentTokenGuard = NDetail::MakeCancelableContextCurrentTokenGuard(Context_);
std::vector<TClosure> capturedCallbacks;
capturedCallbacks.reserve(callbacks.size());
diff --git a/yt/yt/core/actions/cancelation_token-inl.h b/yt/yt/core/actions/cancelation_token-inl.h
deleted file mode 100644
index 682b18be19e..00000000000
--- a/yt/yt/core/actions/cancelation_token-inl.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef CANCELATION_TOKEN_INL_H_
-#error "Direct inclusion of this file is not allowed, include cancelation_token.h"
-// For the sake of sane code completion.
-#include "cancelation_token.h"
-#endif
-
-namespace NYT::NDetail {
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TDecayedConcrete>
-constexpr TDecayedConcrete& TAnyCancelationToken::TStorage::AsConcrete() & noexcept
-{
- using TPtr = TDecayedConcrete*;
-
- if constexpr (SmallToken<TDecayedConcrete>) {
- return *std::launder(reinterpret_cast<TPtr>(&Storage_));
- } else {
- return *static_cast<TPtr>(*std::launder(reinterpret_cast<void**>(&Storage_)));
- }
-}
-
-template <class TDecayedConcrete>
-constexpr const TDecayedConcrete& TAnyCancelationToken::TStorage::AsConcrete() const & noexcept
-{
- using TPtr = const TDecayedConcrete*;
-
- if constexpr (SmallToken<TDecayedConcrete>) {
- return *std::launder(reinterpret_cast<TPtr>(&Storage_));
- } else {
- return *static_cast<TPtr>(*std::launder(reinterpret_cast<void const* const*>(&Storage_)));
- }
-}
-
-template <class TDecayedConcrete>
-constexpr TDecayedConcrete&& TAnyCancelationToken::TStorage::AsConcrete() && noexcept
-{
- using TPtr = TDecayedConcrete*;
-
- if constexpr (SmallToken<TDecayedConcrete>) {
- return std::move(*std::launder(reinterpret_cast<TPtr>(&Storage_)));
- } else {
- return std::move(*static_cast<TPtr>(*std::launder(reinterpret_cast<void**>(&Storage_))));
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <CCancelationToken TDecayedConcrete>
-TAnyCancelationToken::TVTable TAnyCancelationToken::TVTable::Create() noexcept
-{
- TVTable table = {};
- table.Dtor_ = +[] (TStorage& what) {
- TAlloc allocator = {};
-
- auto* ptr = &what.template AsConcrete<TDecayedConcrete>();
- std::destroy_at(ptr);
-
- if constexpr (!SmallToken<TDecayedConcrete>) {
- TTraits::deallocate(allocator, reinterpret_cast<std::byte*>(ptr), sizeof(TDecayedConcrete));
- }
- };
-
- table.CopyCtor_ = +[] (TStorage& where, const TStorage& what) -> void {
- TAlloc allocator = {};
-
- if constexpr (SmallToken<TDecayedConcrete>) {
- where.Set();
- } else {
- where.Set(TTraits::allocate(allocator, sizeof(TDecayedConcrete)));
- }
-
- TTraits::template construct<TDecayedConcrete>(
- allocator,
- &where.template AsConcrete<TDecayedConcrete>(),
- what.template AsConcrete<TDecayedConcrete>());
- };
-
- table.MoveCtor_ = +[] (TStorage& where, TStorage&& what) -> void {
- if constexpr (SmallToken<TDecayedConcrete>) {
- TAlloc allocator = {};
-
- where.Set();
-
- TTraits::template construct<TDecayedConcrete>(
- allocator,
- &where.template AsConcrete<TDecayedConcrete>(),
- std::move(what).template AsConcrete<TDecayedConcrete>());
- TTraits::template destroy<TDecayedConcrete>(
- allocator,
- &what.template AsConcrete<TDecayedConcrete>());
- } else {
- where.Set(static_cast<void*>(&what));
- }
- };
-
- table.IsCancelationRequested_ = +[] (const TStorage& what) -> bool {
- return what.template AsConcrete<TDecayedConcrete>().IsCancelationRequested();
- };
-
- table.CancellationError_ = +[] (const TStorage& what) -> const TError& {
- return what.template AsConcrete<TDecayedConcrete>().GetCancelationError();
- };
-
- return table;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-template <class TToken>
- requires (!std::same_as<TAnyCancelationToken, std::remove_cvref_t<TToken>> &&
- CCancelationToken<std::remove_cvref_t<TToken>>)
-TAnyCancelationToken::TAnyCancelationToken(TToken&& token)
-{
- Set<TToken>(std::forward<TToken>(token));
-}
-
-template <class TToken>
-void TAnyCancelationToken::Set(TToken&& token)
-{
- using TDecayed = std::remove_cvref_t<TToken>;
- TAlloc allocator = {};
-
- Reset();
-
- VTable_ = &StaticTable<TDecayed>;
-
- if constexpr (SmallToken<TDecayed>) {
- Storage_.Set();
- } else {
- Storage_.Set(TTraits::allocate(allocator, sizeof(TDecayed)));
- }
-
- TTraits::template construct<TDecayed>(
- allocator,
- &Storage_.template AsConcrete<TDecayed>(),
- std::forward<TToken>(token));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-} // namespace NYT::NDetail
diff --git a/yt/yt/core/actions/cancelation_token.cpp b/yt/yt/core/actions/cancelation_token.cpp
index c848df61efc..91901aba6ca 100644
--- a/yt/yt/core/actions/cancelation_token.cpp
+++ b/yt/yt/core/actions/cancelation_token.cpp
@@ -9,150 +9,20 @@ namespace NYT::NDetail {
////////////////////////////////////////////////////////////////////////////////
-void TAnyCancelationToken::TStorage::Set(void* ptr) noexcept
+struct TNullToken
{
- std::construct_at<void*>(reinterpret_cast<void**>(Storage_), ptr);
-}
-
-void TAnyCancelationToken::TStorage::Set() noexcept
-{
- std::construct_at(Storage_);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TAnyCancelationToken::TVTable::TDtor TAnyCancelationToken::TVTable::Dtor() const noexcept
-{
- return Dtor_;
-}
-
-TAnyCancelationToken::TVTable::TCopyCtor TAnyCancelationToken::TVTable::CopyCtor() const noexcept
-{
- return CopyCtor_;
-}
-
-TAnyCancelationToken::TVTable::TMoveCtor TAnyCancelationToken::TVTable::MoveCtor() const noexcept
-{
- return MoveCtor_;
-}
-
-TAnyCancelationToken::TVTable::TIsCancelationRequested TAnyCancelationToken::TVTable::IsCancelationRequested() const noexcept
-{
- return IsCancelationRequested_;
-}
-
-TAnyCancelationToken::TVTable::TCancellationError TAnyCancelationToken::TVTable::GetCancelationError() const noexcept
-{
- return CancellationError_;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-TAnyCancelationToken::TAnyCancelationToken(TAnyCancelationToken&& other) noexcept
- : VTable_(other.VTable_)
-{
- if (VTable_) {
- auto moveCtor = VTable_->MoveCtor();
- moveCtor(Storage_, std::move(other.Storage_));
-
- other.VTable_ = nullptr;
- }
-}
-
-TAnyCancelationToken& TAnyCancelationToken::operator= (TAnyCancelationToken&& other) noexcept
-{
- if (this == &other) {
- return *this;
- }
-
- Reset();
-
- VTable_ = other.VTable_;
-
- if (VTable_) {
- auto moveCtor = VTable_->MoveCtor();
- moveCtor(Storage_, std::move(other.Storage_));
-
- other.VTable_ = nullptr;
- }
-
- return *this;
-}
-
-TAnyCancelationToken::TAnyCancelationToken(const TAnyCancelationToken& other) noexcept
- : VTable_(other.VTable_)
-{
- if (VTable_) {
- auto copyCtor = VTable_->CopyCtor();
- copyCtor(Storage_, other.Storage_);
- }
-}
-
-TAnyCancelationToken& TAnyCancelationToken::operator= (const TAnyCancelationToken& other) noexcept
-{
- if (this == &other) {
- return *this;
- }
-
- Reset();
- VTable_ = other.VTable_;
-
- if (VTable_) {
- auto copyCtor = VTable_->CopyCtor();
- copyCtor(Storage_, other.Storage_);
- }
-
- return *this;
-}
-
-TAnyCancelationToken::operator bool() const noexcept
-{
- return VTable_ != nullptr;
-}
-
-TAnyCancelationToken::~TAnyCancelationToken()
-{
- Reset();
-}
-
-bool TAnyCancelationToken::IsCancelationRequested() const noexcept
-{
- if (!VTable_) {
+ friend bool TagInvoke(TTagInvokeTag<IsCancelationRequested>, const TNullToken&) noexcept
+ {
return false;
}
- return VTable_->IsCancelationRequested()(Storage_);
-}
-
-const TError& TAnyCancelationToken::GetCancelationError() const noexcept
-{
- YT_VERIFY(VTable_);
- return VTable_->GetCancelationError()(Storage_);
-}
-
-void TAnyCancelationToken::Reset() noexcept
-{
- if (VTable_) {
- auto dtor = VTable_->Dtor();
- dtor(Storage_);
- VTable_ = nullptr;
+ friend const TError& TagInvoke(TTagInvokeTag<GetCancelationError>, const TNullToken&) noexcept
+ {
+ YT_ABORT();
}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-NConcurrency::TFlsSlot<TAnyCancelationToken> GlobalToken = {};
-
-////////////////////////////////////////////////////////////////////////////////
-
-TCurrentCancelationTokenGuard::TCurrentCancelationTokenGuard(TAnyCancelationToken nextToken)
- : PrevToken_(std::exchange(*GlobalToken, std::move(nextToken)))
-{ }
+};
-TCurrentCancelationTokenGuard::~TCurrentCancelationTokenGuard()
-{
- std::exchange(*GlobalToken, std::move(PrevToken_));
-}
+static_assert(CCancelationToken<TNullToken>);
////////////////////////////////////////////////////////////////////////////////
@@ -160,14 +30,14 @@ struct TTokenForCancelableContext
{
TCancelableContextPtr Context;
- bool IsCancelationRequested() const noexcept
+ friend bool TagInvoke(TTagInvokeTag<IsCancelationRequested>, const TTokenForCancelableContext& token) noexcept
{
- return Context->IsCanceled();
+ return token.Context->IsCanceled();
}
- const TError& GetCancelationError() const
+ friend const TError& TagInvoke(TTagInvokeTag<GetCancelationError>, const TTokenForCancelableContext& token)
{
- return Context->GetCancelationError();
+ return token.Context->GetCancelationError();
}
};
@@ -183,14 +53,14 @@ struct TTokenForFuture
TFutureState<void>* FutureState;
- bool IsCancelationRequested() const noexcept
+ friend bool TagInvoke(TTagInvokeTag<IsCancelationRequested>, const TTokenForFuture& token) noexcept
{
- return FutureState->IsCanceled();
+ return token.FutureState->IsCanceled();
}
- const TError& GetCancelationError() const
+ friend const TError& TagInvoke(TTagInvokeTag<GetCancelationError>, const TTokenForFuture& token)
{
- return FutureState->GetCancelationError();
+ return token.FutureState->GetCancelationError();
}
};
@@ -210,8 +80,37 @@ TCurrentCancelationTokenGuard MakeCancelableContextCurrentTokenGuard(const TCanc
////////////////////////////////////////////////////////////////////////////////
+NConcurrency::TFlsSlot<TAnyCancelationToken> GlobalToken = {};
+
+namespace {
+
+void EnsureInitialized()
+{
+ [[unlikely]] if (!GlobalToken.IsInitialized()) {
+ *GlobalToken = TNullToken{};
+ }
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+TCurrentCancelationTokenGuard::TCurrentCancelationTokenGuard(TAnyCancelationToken nextToken)
+{
+ EnsureInitialized();
+ PrevToken_ = std::exchange(*GlobalToken, std::move(nextToken));
+}
+
+TCurrentCancelationTokenGuard::~TCurrentCancelationTokenGuard()
+{
+ std::exchange(*GlobalToken, std::move(PrevToken_));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
const TAnyCancelationToken& GetCurrentCancelationToken()
{
+ EnsureInitialized();
return *GlobalToken;
}
diff --git a/yt/yt/core/actions/cancelation_token.h b/yt/yt/core/actions/cancelation_token.h
index f3f28aa5a2b..a9363f7e710 100644
--- a/yt/yt/core/actions/cancelation_token.h
+++ b/yt/yt/core/actions/cancelation_token.h
@@ -4,119 +4,40 @@
#include <yt/yt/core/misc/error.h>
+#include <library/cpp/yt/memory/type_erasure.h>
+#include <library/cpp/yt/misc/tag_invoke_cpo.h>
+
namespace NYT::NDetail {
////////////////////////////////////////////////////////////////////////////////
+struct TIsCancelationRequestedFn
+ : public TTagInvokeCpoBase<TIsCancelationRequestedFn>
+{ };
+
+struct TGetCancelationErrorFn
+ : public TTagInvokeCpoBase<TGetCancelationErrorFn>
+{ };
+
+inline constexpr TIsCancelationRequestedFn IsCancelationRequested = {};
+inline constexpr TGetCancelationErrorFn GetCancelationError = {};
+
+////////////////////////////////////////////////////////////////////////////////
+
// CancelToken is an entity which you can ask whether cancellation has been
// requested or not. If it has been requested, you can ask for cancelation error.
template <class T>
-concept CCancelationToken = requires (T& t) {
- { t.IsCancelationRequested() } -> std::same_as<bool>;
- { t.GetCancelationError() } -> std::same_as<const TError&>;
-} && std::copyable<T>;
+concept CCancelationToken =
+ std::copyable<T> &&
+ CTagInvocableS<TIsCancelationRequestedFn, bool(const T&) noexcept> &&
+ CTagInvocableS<TGetCancelationErrorFn, const TError&(const T&)>;
////////////////////////////////////////////////////////////////////////////////
// We need to read/write global variable which satisfies concept CCancelationToken.
-class TAnyCancelationToken
-{
-private:
- static constexpr size_t SmallTokenSize = sizeof(void*) * 2;
- static constexpr size_t SmallTokenAlign = SmallTokenSize;
-
- template <class T>
- static constexpr bool SmallToken =
- (sizeof(T) <= SmallTokenSize) &&
- (alignof(T) <= SmallTokenAlign);
-
- using TAlloc = std::allocator<std::byte>;
- using TTraits = std::allocator_traits<TAlloc>;
-
- class TStorage
- {
- public:
- TStorage() = default;
-
- /*constexpr in C++23*/ void Set(void* ptr) noexcept;
- /*constexpr in C++23*/ void Set() noexcept;
-
- template <class TDecayedConcrete>
- constexpr TDecayedConcrete& AsConcrete() & noexcept;
-
- template <class TDecayedConcrete>
- constexpr const TDecayedConcrete& AsConcrete() const & noexcept;
-
- template <class TDecayedConcrete>
- constexpr TDecayedConcrete&& AsConcrete() && noexcept;
-
- private:
- alignas(SmallTokenAlign) std::byte Storage_[SmallTokenSize];
- };
-
- class TVTable
- {
- private:
- using TDtor = void(*)(TStorage& what);
- using TCopyCtor = void (*)(TStorage& where, const TStorage& what);
- using TMoveCtor = void (*)(TStorage& where, TStorage&& what);
- using TIsCancelationRequested = bool (*)(const TStorage& what);
- using TCancellationError = const TError& (*)(const TStorage& what);
-
- public:
- template <CCancelationToken TDecayedConcrete>
- static TVTable Create() noexcept;
-
- TDtor Dtor() const noexcept;
- TCopyCtor CopyCtor() const noexcept;
- TMoveCtor MoveCtor() const noexcept;
- TIsCancelationRequested IsCancelationRequested() const noexcept;
- TCancellationError GetCancelationError() const noexcept;
-
- private:
- TDtor Dtor_ = nullptr;
- TCopyCtor CopyCtor_ = nullptr;
- TMoveCtor MoveCtor_ = nullptr;
- TIsCancelationRequested IsCancelationRequested_ = nullptr;
- TCancellationError CancellationError_ = nullptr;
-
- TVTable() = default;
- };
-
- // Consider inline vtable storage.
- template <CCancelationToken TToken>
- static inline TVTable StaticTable = TVTable::template Create<TToken>();
-
-public:
- TAnyCancelationToken() = default;
-
- template <class TToken>
- requires (!std::same_as<TAnyCancelationToken, std::remove_cvref_t<TToken>> &&
- CCancelationToken<std::remove_cvref_t<TToken>>)
- TAnyCancelationToken(TToken&& token);
-
- TAnyCancelationToken(TAnyCancelationToken&& other) noexcept;
- TAnyCancelationToken& operator= (TAnyCancelationToken&& other) noexcept;
-
- TAnyCancelationToken(const TAnyCancelationToken& other) noexcept;
- TAnyCancelationToken& operator= (const TAnyCancelationToken& other) noexcept;
-
- explicit operator bool() const noexcept;
-
- ~TAnyCancelationToken();
-
- bool IsCancelationRequested() const noexcept;
- const TError& GetCancelationError() const noexcept;
-
-private:
- TStorage Storage_ = {};
- TVTable* VTable_ = nullptr;
-
- void Reset() noexcept;
-
- template <class TToken>
- void Set(TToken&& token);
-};
+using TAnyCancelationToken = ::NYT::TAnyObject<
+ TOverload<IsCancelationRequested, bool(const TErasedThis&) noexcept>,
+ TOverload<GetCancelationError, const TError&(const TErasedThis&)>>;
////////////////////////////////////////////////////////////////////////////////
@@ -145,7 +66,3 @@ const TAnyCancelationToken& GetCurrentCancelationToken();
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT::NDetail
-
-#define CANCELATION_TOKEN_INL_H_
-#include "cancelation_token-inl.h"
-#undef CANCELATION_TOKEN_INL_H_
diff --git a/yt/yt/core/actions/future-inl.h b/yt/yt/core/actions/future-inl.h
index 4ed31b8db8a..32b0cf30ec1 100644
--- a/yt/yt/core/actions/future-inl.h
+++ b/yt/yt/core/actions/future-inl.h
@@ -52,13 +52,13 @@ inline TError TryExtractCancelationError()
{
const auto& currentToken = GetCurrentCancelationToken();
- if (currentToken.IsCancelationRequested()) {
+ if (IsCancelationRequested(currentToken)) {
// NB(arkady-e1ppa): This clown fiesta is present because some external
// users managed to both hardcode "Promise abandoned" error message
// as the retriable one (or expected in tests) and
// rely on their cancelation error to never be wrapped
// into anything with a different error code.
- const auto& tokenError = currentToken.GetCancelationError();
+ const auto& tokenError = GetCancelationError(currentToken);
return TError(tokenError.GetCode(), "Promise abandoned") << tokenError;
}
diff --git a/yt/yt/core/actions/unittests/cancelation_token_ut.cpp b/yt/yt/core/actions/unittests/cancelation_token_ut.cpp
index 6406450ccd0..babf613a0b8 100644
--- a/yt/yt/core/actions/unittests/cancelation_token_ut.cpp
+++ b/yt/yt/core/actions/unittests/cancelation_token_ut.cpp
@@ -9,14 +9,14 @@ namespace {
struct TSimpleToken
{
- bool IsCancelationRequested() const noexcept
+ friend bool TagInvoke(TTagInvokeTag<IsCancelationRequested>, const TSimpleToken& token) noexcept
{
- return !Error.IsOK();
+ return !token.Error.IsOK();
}
- const TError& GetCancelationError() const noexcept
+ friend const TError& TagInvoke(TTagInvokeTag<GetCancelationError>, const TSimpleToken& token)
{
- return Error;
+ return token.Error;
}
TError Error;
@@ -72,7 +72,7 @@ TEST(TAnyTokenTest, JustWorks)
{
ResetCounters();
TAnyCancelationToken any{TSimpleToken{}};
- EXPECT_FALSE(any.IsCancelationRequested());
+ EXPECT_FALSE(IsCancelationRequested(any));
}
TEST(TAnyTokenTest, Copy)
@@ -85,26 +85,27 @@ TEST(TAnyTokenTest, Copy)
EXPECT_EQ(TSimpleToken::CopyCount, 1);
EXPECT_EQ(TSimpleToken::MoveCount, 0);
- EXPECT_TRUE(any.IsCancelationRequested());
+ EXPECT_TRUE(IsCancelationRequested(any));
token.Error = TError{};
TAnyCancelationToken any1{};
- // NB: Implicit move ctor.
+ // NB: Implicit copy ctor and then move assign.
any1 = token;
+
EXPECT_EQ(TSimpleToken::CtorCount, 0);
EXPECT_EQ(TSimpleToken::CopyCount, 2);
EXPECT_EQ(TSimpleToken::MoveCount, 1);
EXPECT_EQ(TSimpleToken::DtorCount, 1);
- EXPECT_FALSE(any1.IsCancelationRequested());
+ EXPECT_FALSE(IsCancelationRequested(any1));
any1 = any;
EXPECT_EQ(TSimpleToken::CtorCount, 0);
EXPECT_EQ(TSimpleToken::CopyCount, 3);
EXPECT_EQ(TSimpleToken::MoveCount, 1);
EXPECT_EQ(TSimpleToken::DtorCount, 2);
- EXPECT_TRUE(any1.IsCancelationRequested());
+ EXPECT_TRUE(IsCancelationRequested(any1));
}
TEST(TAnyTokenTest, MoveSmallToken)
@@ -117,7 +118,7 @@ TEST(TAnyTokenTest, MoveSmallToken)
EXPECT_EQ(TSimpleToken::CopyCount, 0);
EXPECT_EQ(TSimpleToken::MoveCount, 1);
- EXPECT_TRUE(any.IsCancelationRequested());
+ EXPECT_TRUE(IsCancelationRequested(any));
token.Error = TError{};
@@ -132,14 +133,14 @@ TEST(TAnyTokenTest, MoveSmallToken)
EXPECT_EQ(TSimpleToken::CopyCount, 0);
EXPECT_EQ(TSimpleToken::MoveCount, 3);
EXPECT_EQ(TSimpleToken::DtorCount, 1);
- EXPECT_FALSE(any1.IsCancelationRequested());
+ EXPECT_FALSE(IsCancelationRequested(any1));
any1 = std::move(any);
EXPECT_EQ(TSimpleToken::CtorCount, 0);
EXPECT_EQ(TSimpleToken::CopyCount, 0);
EXPECT_EQ(TSimpleToken::MoveCount, 4);
EXPECT_EQ(TSimpleToken::DtorCount, 3);
- EXPECT_TRUE(any1.IsCancelationRequested());
+ EXPECT_TRUE(IsCancelationRequested(any1));
}
////////////////////////////////////////////////////////////////////////////////