mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 16:56:44 +08:00
Add trap and unreachable
* Use both functions to exit on invalid behaviour
This commit is contained in:
parent
54fb32ae56
commit
60c73a1a48
@ -387,9 +387,9 @@ struct error_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Workaround for GCC bug:
|
/// Once this was a workaround for GCC bug:
|
||||||
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
|
||||||
struct empty_callback {
|
struct final_callback {
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
void operator()(Args... /*args*/) {
|
void operator()(Args... /*args*/) {
|
||||||
}
|
}
|
||||||
@ -398,7 +398,14 @@ struct empty_callback {
|
|||||||
void set_value(Args... /*args*/) {
|
void set_value(Args... /*args*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_exception(types::error_type /*error*/) {
|
void set_exception(types::error_type error) {
|
||||||
|
(void)error;
|
||||||
|
#ifndef CONTINUABLE_WITH_UNHANDLED_ERRORS
|
||||||
|
// There were unhandled errors inside the asynchronous call chain!
|
||||||
|
// Define `CONTINUABLE_WITH_UNHANDLED_ERRORS` in order
|
||||||
|
// to ignore unhandled errors!"
|
||||||
|
util::trap();
|
||||||
|
#endif // CONTINUABLE_WITH_UNHANDLED_ERRORS
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace callbacks
|
} // namespace callbacks
|
||||||
@ -518,7 +525,7 @@ auto chain_error_handler(Continuation&& continuation, Callback&& callback,
|
|||||||
template <typename Continuation>
|
template <typename Continuation>
|
||||||
void finalize_continuation(Continuation&& continuation) {
|
void finalize_continuation(Continuation&& continuation) {
|
||||||
attorney::invoke_continuation(std::forward<Continuation>(continuation),
|
attorney::invoke_continuation(std::forward<Continuation>(continuation),
|
||||||
callbacks::empty_callback{});
|
callbacks::final_callback{});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Workaround for GCC bug:
|
/// Workaround for GCC bug:
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <continuable/detail/api.hpp>
|
#include <continuable/detail/api.hpp>
|
||||||
|
#include <continuable/detail/traits.hpp>
|
||||||
#include <continuable/detail/util.hpp>
|
#include <continuable/detail/util.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
#include <continuable/detail/features.hpp>
|
#include <continuable/detail/features.hpp>
|
||||||
#include <continuable/detail/hints.hpp>
|
#include <continuable/detail/hints.hpp>
|
||||||
#include <continuable/detail/types.hpp>
|
#include <continuable/detail/types.hpp>
|
||||||
|
#include <continuable/detail/util.hpp>
|
||||||
|
|
||||||
namespace cti {
|
namespace cti {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -92,13 +93,19 @@ public:
|
|||||||
void operator()(Args... args) {
|
void operator()(Args... args) {
|
||||||
this->resolve(promise_, std::move(args)...);
|
this->resolve(promise_, std::move(args)...);
|
||||||
}
|
}
|
||||||
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
|
|
||||||
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
|
|
||||||
/// Resolves the promise through the exception
|
/// Resolves the promise through the exception
|
||||||
void operator()(types::dispatch_error_tag, types::error_type error) {
|
void operator()(types::dispatch_error_tag, types::error_type error) {
|
||||||
|
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
|
||||||
|
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
|
||||||
promise_.set_exception(error);
|
promise_.set_exception(error);
|
||||||
}
|
#else
|
||||||
|
// Can't forward a std::error_condition or custom error type
|
||||||
|
// to a std::promise. Handle the error first in order
|
||||||
|
// to prevent this trap!
|
||||||
|
util::trap();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the future from the promise
|
/// Returns the future from the promise
|
||||||
auto get_future() {
|
auto get_future() {
|
||||||
|
|||||||
@ -241,6 +241,27 @@ private:
|
|||||||
/// Is true when the automatic invocation on destruction is disabled
|
/// Is true when the automatic invocation on destruction is disabled
|
||||||
bool frozen_ : 1;
|
bool frozen_ : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Hint for the compiler that this point should be unreachable
|
||||||
|
[[noreturn]] inline void unreachable() {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__assume(false);
|
||||||
|
#elif __has_builtin(__builtin_unreachable)
|
||||||
|
__builtin_unreachable();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Causes the application to exit abnormally because we are
|
||||||
|
/// in an invalid state.
|
||||||
|
[[noreturn]] inline void trap() {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
__debugbreak();
|
||||||
|
#elif __has_builtin(__builtin_trap)
|
||||||
|
__builtin_trap();
|
||||||
|
#else
|
||||||
|
*(volatile int*)0 = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user