35#include <asio/any_io_executor.hpp>
36#include <asio/cancellation_signal.hpp>
37#include <asio/post.hpp>
49namespace neograph::graph {
64 : std::runtime_error(
"neograph: run cancelled") {}
66 : std::runtime_error(
"neograph: run cancelled — " + detail) {}
98 if (cancelled_.exchange(
true, std::memory_order_acq_rel)) {
104 asio::any_io_executor ex_snapshot;
106 std::lock_guard<std::mutex> lk(mu_);
113 asio::post(ex_snapshot, [
this]() {
114 sig_.emit(asio::cancellation_type::all);
128 std::vector<std::shared_ptr<CancelToken>> live_children;
130 std::lock_guard<std::mutex> lk(children_mu_);
131 live_children.reserve(children_.size());
132 for (
auto& w : children_) {
133 if (
auto sp = w.lock()) {
134 live_children.push_back(std::move(sp));
141 for (
auto& child : live_children) {
148 return cancelled_.load(std::memory_order_acquire);
161 bool fire_immediately =
false;
163 std::lock_guard<std::mutex> lk(mu_);
165 fire_immediately = cancelled_.load(std::memory_order_acquire);
167 if (fire_immediately) {
168 std::lock_guard<std::mutex> lk(mu_);
170 asio::post(ex_, [
this]() {
171 sig_.emit(asio::cancellation_type::all);
186 asio::cancellation_slot
slot() noexcept {
195 if (is_cancelled()) {
233 [[nodiscard]] std::shared_ptr<CancelToken>
fork() {
237 auto child = std::shared_ptr<CancelToken>(
new CancelToken());
240 std::lock_guard<std::mutex> lk(children_mu_);
249 children_.begin(), children_.end(),
250 [](
const std::weak_ptr<CancelToken>& w) {
254 children_.push_back(child);
260 if (cancelled_.load(std::memory_order_acquire)) {
267 std::atomic<bool> cancelled_{
false};
268 mutable std::mutex mu_;
269 asio::any_io_executor ex_;
270 asio::cancellation_signal sig_;
277 mutable std::mutex children_mu_;
278 std::vector<std::weak_ptr<CancelToken>> children_;
NEOGRAPH_API export/import macro for shared-library builds.
Cooperative cancel primitive shared between caller and engine.
void throw_if_cancelled(const std::string &detail={}) const
Throws CancelledException if cancelled.
void bind_executor(asio::any_io_executor ex)
Bind the executor that will handle cancellation_signal emits.
asio::cancellation_slot slot() noexcept
Cancellation slot for binding to a coroutine via asio::bind_cancellation_slot at co_spawn.
void cancel() noexcept
Request cancellation.
bool is_cancelled() const noexcept
Polling read of the cancel flag. Cheap, lock-free.
std::shared_ptr< CancelToken > fork()
Create a child token that cascades from this one.
Thrown by the engine when a run is cancelled mid-flight via CancelToken::cancel().