You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
2.1 KiB
57 lines
2.1 KiB
//! Sync errors
|
|
#pragma once
|
|
|
|
#include <stop_token>
|
|
#include <stdexcept>
|
|
|
|
namespace fx::error {
|
|
/// Thrown when an operation is aborted via a stop signal.
|
|
///
|
|
/// The state may be inconsistent after the thrown exception.
|
|
struct OperationCancelledError : virtual std::runtime_error {
|
|
OperationCancelledError() noexcept;
|
|
OperationCancelledError(OperationCancelledError const&) noexcept = default;
|
|
OperationCancelledError& operator=(OperationCancelledError const&) noexcept = default;
|
|
|
|
virtual ~OperationCancelledError();
|
|
};
|
|
|
|
/// Thrown when a task is cancelled via a stop signal.
|
|
///
|
|
/// The state is **not** left in an inconsistent state after the thrown exception.
|
|
struct TaskCancelledError final : OperationCancelledError {
|
|
TaskCancelledError() noexcept;
|
|
TaskCancelledError(TaskCancelledError const&) noexcept = default;
|
|
TaskCancelledError& operator=(TaskCancelledError const&) noexcept = default;
|
|
|
|
virtual ~TaskCancelledError();
|
|
};
|
|
|
|
// Throw an `OperationCancelledError` (or, optionally, a `TaskCancelledError` if there is a completed task that was cancelled instead of an operation being aborted.)
|
|
[[gnu::noinline, gnu::cold, noreturn]]
|
|
void throw_cancelled(bool clean = false);
|
|
|
|
[[gnu::gnu_inline]]
|
|
extern inline
|
|
void throw_if_cancelled(std::stop_token const& st, bool clean = false) {
|
|
if(not st.stop_requested()) return;
|
|
else
|
|
throw_cancelled(clean);
|
|
}
|
|
|
|
namespace details [[gnu::visibility("internal")]] {
|
|
// NOTE: This assumes the existence of `extern "C" void ::throw_last_system_error()` which throws the current `errno` as a generic-categoried `std::system_error`. If that does not exist, it is re-implemented below. (XXX: There is no reason for this now? We have an impl to call... Ffs...) //
|
|
static void throw_last_system_error() __attribute__((cold, noreturn, weakref("throw_last_system_error")));
|
|
}
|
|
|
|
[[gnu::gnu_inline, gnu::cold, noreturn]]
|
|
extern inline
|
|
void throw_last_system_error()
|
|
{
|
|
if(__builtin_expect(details::throw_last_system_error != nullptr, true))
|
|
details::throw_last_system_error();
|
|
else (&throw_last_system_error)();
|
|
__builtin_unreachable();
|
|
}
|
|
}
|