From 9994cd43c2465d00fb4f465f95e0edca9f6ca9b9 Mon Sep 17 00:00:00 2001 From: ponasenko-rs Date: Thu, 21 Nov 2024 16:59:36 +0300 Subject: [PATCH] YT-23585: Fix race between Cancel and GetCanceledError in Canceler commit_hash:2c1b31d95037975cf4703cb90f81232f880a37e6 --- .../concurrency/fiber_scheduler_thread.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/yt/yt/core/concurrency/fiber_scheduler_thread.cpp b/yt/yt/core/concurrency/fiber_scheduler_thread.cpp index 441d093a4..72130a671 100644 --- a/yt/yt/core/concurrency/fiber_scheduler_thread.cpp +++ b/yt/yt/core/concurrency/fiber_scheduler_thread.cpp @@ -621,7 +621,17 @@ class TCanceler void SetFuture(TFuture awaitable) { auto guard = Guard(Lock_); - Future_ = std::move(awaitable); + if (!IsCanceled()) { + Future_ = std::move(awaitable); + return; + } + + guard.Release(); + + ErrorSet_.Wait(); + + YT_ASSERT(!CancelationError_.IsOK()); + awaitable.Cancel(CancelationError_); } void ResetFuture() @@ -644,6 +654,8 @@ class TCanceler future = std::move(Future_); } + ErrorSet_.NotifyAll(); + if (future) { YT_LOG_DEBUG("Sending cancelation to fiber, propagating to the awaited future (TargetFiberId: %x)", FiberId_); @@ -654,12 +666,6 @@ class TCanceler } } - TError GetCancelationError() const - { - auto guard = Guard(Lock_); - return CancelationError_; - } - void Run(const TError& error) { Cancel(error); @@ -680,6 +686,7 @@ class TCanceler const TFiberId FiberId_; std::atomic Canceled_ = false; + NThreading::TEvent ErrorSet_; NThreading::TSpinLock Lock_; TError CancelationError_; TFuture Future_; @@ -1173,10 +1180,6 @@ void WaitUntilSet(TFuture future, IInvokerPtr invoker) GetCurrentFiberCanceler(); const auto& canceler = NDetail::GetFiberSwitchHandler()->Canceler(); - if (canceler->IsCanceled()) { - future.Cancel(canceler->GetCancelationError()); - } - canceler->SetFuture(future); auto finally = Finally([&] { canceler->ResetFuture();