chriskohlhoff / asio

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

asio::experimental::channel: try_send immediately after cancel always fails #1241

Closed erinacio closed 1 year ago

erinacio commented 1 year ago

MRE:

#include <asio.hpp>
#include <asio/experimental/channel.hpp>
#include <iostream>

asio::awaitable<void> async_main() {
  auto ex = co_await asio::this_coro::executor;
  asio::experimental::channel<void(std::error_code, int)> channel_{ex, 16};
  asio::co_spawn(
      ex,
      [](auto &ch) -> asio::awaitable<void> {
        co_await ch.async_receive(asio::as_tuple(asio::use_awaitable));
      }(channel_),
      asio::detached);
  asio::steady_timer timer{ex, std::chrono::milliseconds{1}};
  // make sure async_receive is awaiting
  co_await timer.async_wait(asio::as_tuple(asio::use_awaitable));
  channel_.cancel();
  bool ok = channel_.try_send(std::error_code{}, 1);
  std::clog << "try send ok? " << ok << std::endl;
}

int main() {
  asio::io_context io{1};
  asio::co_spawn(io, async_main(), asio::detached);
  io.run();
  return 0;
}

got

try send ok? 0

on asio 1.24.0 and asio latest master commit with gcc 12.2.1 and clang 15.0.7 on Arch Linux.

According to the documentation, this behavior is not expected as the channel is apparently not full.

erinacio commented 1 year ago

1242 merged externally