Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Bug: should_originate_on_cancel does not cancel certain awaiters or duplicated actions.

オープン
#1,617 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
cpp

調査の方向性

impl::check_status_canceled、await_adapter::await_resume、timespan_awaiter::await_resume、signal_awaiter::await_resume におけるキャンセル処理を追跡する。繰り返し発生するキャンセルによって originate-on-cancel 設定が復元されないこと、および resume_after と resume_on_signal が originate_on_cancel(false) を尊重することを確認する。繰り返しのシナリオと列挙された awaiter シナリオのカバレッジを追加または更新する。

索引モデルが issue の本文から書いたものです。

説明

Version

3.0.260715.1

Summary
  1. #1512 introduced the setter originate_on_cancel and getter should_originate_on_cancel. The await_resume task would call originate_on_cancel (the setter) to check whether to RoOriginate the call. This is a bug, because the setter has a side effect. Its parameter defaults to true, so each call does std::exchange(m_originate_on_cancel, true): it returns the previous value, so the first check behaved correctly, and then wrote the flag back to true. Every later cancellation on that same promise originated again. A test that cancels only once passes even with the bug present.

IAsyncAction DoWork(HANDLE ready)
{
auto cancel = co_await get_cancellation_token();
cancel.originate_on_cancel(false); // "don't debug spew when I'm cancelled"

co_await resume_on_signal(ready);    // If cancelled before `ready`, doesn't originate.
                                     // The first Cancel() consumes the opt-out, re-arms the flag
co_await CleanupAsync();             // If cancelled after, then the next co_await will 
                                     // call Cancel() again, and since should_originate is true now
                                     // it will Originate, thus causing the debug spew.

}
In addition, there is a missing scenario in the previous PR, it did not account for winrt::resume_after, winrt::resume_on_signal, and
These three awaiter resume paths also threw hresult_canceled unconditionally, so originate_on_cancel(false) had no effect on them at all: impl::check_status_canceled (reached from await_adapter::await_resume for any coroutine awaiting a WinRT async that completes Canceled), timespan_awaiter::await_resume (resume_after) and signal_awaiter::await_resume (resume_on_signal).

Reproducible example
IAsyncAction PollStatusAsync()
{
    auto cancel = co_await get_cancellation_token();
    cancel.enable_propagation();
    cancel.originate_on_cancel(false);

    while (true)
    {
        co_await RefreshAsync();
        co_await resume_after(30s);   // cancelled here -> timespan_awaiter::await_resume
    }                                 //    throws hresult_canceled() -> originates
}
Expected behavior

No response

Actual behavior

No response

Additional comments

No response

主要言語
C++
スター
1.9k
フォーク
281
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/cppwinrt のほかの issue

microsoft/cppwinrt の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。