From 14a1c7511b3081979084b5d78bbbf3f171466490 Mon Sep 17 00:00:00 2001 From: Clyraz <111095996+Clyraz@users.noreply.github.com> Date: Wed, 17 Jun 2026 13:48:00 +0200 Subject: [PATCH 1/3] Fix race conditions in cancellable_promise --- strings/base_coroutine_threadpool.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index 057d5b548..c85e53f9c 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -151,7 +151,7 @@ WINRT_EXPORT namespace winrt void revoke_canceller() { - while (m_canceller.exchange(nullptr, std::memory_order_acquire) == cancelling_ptr) + while (m_canceller.load(std::memory_order_acquire) == cancelling_ptr) { std::this_thread::yield(); } @@ -160,6 +160,11 @@ WINRT_EXPORT namespace winrt 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 +174,7 @@ WINRT_EXPORT namespace winrt } } lock{ this }; - if ((canceller != nullptr) && (canceller != cancelling_ptr)) + if (canceller != nullptr) { canceller(m_context); } From 0031352e93f1d442d1ffeef97de79d90968178be Mon Sep 17 00:00:00 2001 From: Clyraz <111095996+Clyraz@users.noreply.github.com> Date: Thu, 18 Jun 2026 21:23:57 +0200 Subject: [PATCH 2/3] Properly revoke canceller --- strings/base_coroutine_threadpool.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index c85e53f9c..b7dc7e7fb 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -151,10 +151,15 @@ WINRT_EXPORT namespace winrt void revoke_canceller() { - while (m_canceller.load(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() From f0bb08aef49e2f9ceaf76f632b4e7bfd0fdc3067 Mon Sep 17 00:00:00 2001 From: Clyraz <111095996+Clyraz@users.noreply.github.com> Date: Thu, 18 Jun 2026 22:34:27 +0200 Subject: [PATCH 3/3] Format changes --- strings/base_coroutine_threadpool.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/base_coroutine_threadpool.h b/strings/base_coroutine_threadpool.h index b7dc7e7fb..312daef3b 100644 --- a/strings/base_coroutine_threadpool.h +++ b/strings/base_coroutine_threadpool.h @@ -154,8 +154,8 @@ WINRT_EXPORT namespace winrt auto canceller = m_canceller.load(std::memory_order_relaxed); do { - if (canceller == cancelling_ptr) { - + if (canceller == cancelling_ptr) + { std::this_thread::yield(); canceller = nullptr; }