chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.72k stars 1.19k forks source link

coro_promise.get_cancellation_slot() return a wrong slot #1501

Open kuntryn opened 4 days ago

kuntryn commented 4 days ago

The asio::experimental::generator has a asio::cancellation_state that can be accessed by co_await asio::this_coro::cacellation_state, just like asio::awaitable. But the get_cancellation_slot() return the slot that state resides in, not the slot of state,which is diffrent from asio::awaitable's implementation.

https://github.com/chriskohlhoff/asio/blob/79f17e970b6f661c275ad6fe0d7ed448e5e72c27/asio/include/asio/experimental/impl/coro.hpp#L36-L40

https://github.com/chriskohlhoff/asio/blob/79f17e970b6f661c275ad6fe0d7ed448e5e72c27/asio/include/asio/experimental/impl/coro.hpp#L601-L604

https://github.com/chriskohlhoff/asio/blob/79f17e970b6f661c275ad6fe0d7ed448e5e72c27/asio/include/asio/impl/awaitable.hpp#L749-L752

When generator got a token that has a associated cancellation_signal, the cancellation_state will be corrupted by async operation which will emplace a cancellation_handler in slot.

Perhaps the implementatin should be

  cancellation_slot_type get_cancellation_slot() const noexcept
  {
    return cancel ? cancel->state.slot() : cancellation_slot_type{};
  }