Skip to content

Instantly share code, notes, and snippets.

@cbodley
Created May 14, 2024 20:19
Show Gist options
  • Save cbodley/e4a1d07ec6f06d62e31356f7a216fecb to your computer and use it in GitHub Desktop.
Save cbodley/e4a1d07ec6f06d62e31356f7a216fecb to your computer and use it in GitHub Desktop.
#include <chrono>
#include <exception>
#include <latch>
#include <thread>
#include <boost/asio.hpp>
#include <gtest/gtest.h>
using namespace std::chrono_literals;
namespace asio = boost::asio;
void callback(std::exception_ptr eptr)
{
ASSERT_TRUE(eptr);
try {
std::rethrow_exception(eptr);
} catch (const boost::system::system_error& e) {
EXPECT_EQ(e.code(), std::errc::operation_canceled);
} catch (const std::exception&) {
EXPECT_THROW(throw, boost::system::system_error);
}
}
void thread_entry(asio::cancellation_signal& signal,
std::latch& spawned)
{
asio::io_context ctx;
asio::co_spawn(ctx,
[&spawned] () -> asio::awaitable<void> {
spawned.count_down();
asio::steady_timer timer{co_await asio::this_coro::executor, 1h};
co_await timer.async_wait(asio::use_awaitable);
}, bind_cancellation_slot(signal.slot(), callback));
ctx.run();
}
TEST(CoSpawn, Cancel)
{
asio::cancellation_signal signal;
std::latch spawned{1};
auto thread = std::thread{thread_entry, std::ref(signal), std::ref(spawned)};
spawned.wait();
signal.emit(asio::cancellation_type::terminal);
thread.join();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment