| 120 | } |
| 121 | |
| 122 | void test_spawn_cancel() |
| 123 | { |
| 124 | boost::asio::cancellation_signal sig; |
| 125 | boost::asio::io_context ctx; |
| 126 | |
| 127 | std::exception_ptr result = nullptr; |
| 128 | bool called = false; |
| 129 | boost::asio::spawn(ctx, sleeping_coroutine, |
| 130 | boost::asio::bind_cancellation_slot(sig.slot(), |
| 131 | [&](std::exception_ptr e) |
| 132 | { |
| 133 | result = e; |
| 134 | called = true; |
| 135 | })); |
| 136 | |
| 137 | ctx.poll(); |
| 138 | BOOST_ASIO_CHECK(!ctx.stopped()); |
| 139 | |
| 140 | BOOST_ASIO_CHECK(!called); |
| 141 | BOOST_ASIO_CHECK(result == nullptr); |
| 142 | |
| 143 | sig.emit(boost::asio::cancellation_type::all); |
| 144 | |
| 145 | ctx.poll(); |
| 146 | BOOST_ASIO_CHECK(ctx.stopped()); |
| 147 | |
| 148 | BOOST_ASIO_CHECK(called); |
| 149 | BOOST_ASIO_CHECK(result != nullptr); |
| 150 | try |
| 151 | { |
| 152 | std::rethrow_exception(result); |
| 153 | } |
| 154 | catch (const boost::system::system_error& e) |
| 155 | { |
| 156 | BOOST_ASIO_CHECK(e.code() == boost::asio::error::operation_aborted); |
| 157 | } |
| 158 | catch (...) |
| 159 | { |
| 160 | BOOST_ASIO_ERROR("expected system_error"); |
| 161 | } |
| 162 | } |
| 163 | |
| 164 | void throwing_coroutine(boost::asio::yield_context) |
| 165 | { |