diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index 057d5b548..312daef3b 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -151,15 +151,25 @@ WINRT_EXPORT namespace winrt void revoke_canceller() { - while (m_canceller.exchange(nullptr, std::memory_order_acquire) == cancelling_ptr) + auto canceller = m_canceller.load(std::memory_order_relaxed); + do { - std::this_thread::yield(); - } + if (canceller == cancelling_ptr) + { + std::this_thread::yield(); + canceller = nullptr; + } + } while (!m_canceller.compare_exchange_strong(canceller, nullptr, std::memory_order_acquire, std::memory_order_relaxed)); } void cancel() { auto canceller = m_canceller.exchange(cancelling_ptr, std::memory_order_acquire); + if (canceller == cancelling_ptr) + { + return; + } + struct unique_cancellation_lock { cancellable_promise* promise; @@ -169,7 +179,7 @@ WINRT_EXPORT namespace winrt } } lock{ this }; - if ((canceller != nullptr) && (canceller != cancelling_ptr)) + if (canceller != nullptr) { canceller(m_context); }