Added (pretty limited) support for uncaught exceptions in coroutines.
This commit is contained in:
parent
dff7b30b2d
commit
0b8772c952
@ -455,11 +455,15 @@ public:
|
|||||||
std::function<void(StoredTask&)> setFuture;
|
std::function<void(StoredTask&)> setFuture;
|
||||||
std::any resultData;
|
std::any resultData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using exception_handler_t = std::function<void(std::exception_ptr)>;
|
||||||
protected:
|
protected:
|
||||||
using task_vector_t = std::vector<StoredTask>;
|
using task_vector_t = std::vector<StoredTask>;
|
||||||
|
|
||||||
template<typename TTask>
|
template<typename TTask>
|
||||||
using wrapped_task_ptr_t = std::unique_ptr<WrappedTask<TTask>>;
|
using wrapped_task_ptr_t = std::unique_ptr<WrappedTask<TTask>>;
|
||||||
|
|
||||||
|
exception_handler_t uncaughtExceptionHandler_;
|
||||||
public:
|
public:
|
||||||
TaskLoop() = default;
|
TaskLoop() = default;
|
||||||
TaskLoop(const TaskLoop&) = delete;
|
TaskLoop(const TaskLoop&) = delete;
|
||||||
@ -469,6 +473,8 @@ public:
|
|||||||
TaskLoop& operator=(const TaskLoop&) = delete;
|
TaskLoop& operator=(const TaskLoop&) = delete;
|
||||||
TaskLoop& operator=(TaskLoop&&) = delete;
|
TaskLoop& operator=(TaskLoop&&) = delete;
|
||||||
|
|
||||||
|
void setUncaughtExceptionHandler(exception_handler_t handler) noexcept { uncaughtExceptionHandler_ = std::move(handler); }
|
||||||
|
|
||||||
template<typename TResult>
|
template<typename TResult>
|
||||||
inline FuturePtr<TResult> addTask(TaskBase<TResult> task, TaskHandle* outHandle = nullptr) noexcept;
|
inline FuturePtr<TResult> addTask(TaskBase<TResult> task, TaskHandle* outHandle = nullptr) noexcept;
|
||||||
|
|
||||||
@ -477,7 +483,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] static TaskLoop& current() noexcept;
|
[[nodiscard]] static TaskLoop& current() noexcept;
|
||||||
protected:
|
protected:
|
||||||
inline TaskStatus tickTask(StoredTask& task) noexcept;
|
inline TaskStatus tickTask(StoredTask& task);
|
||||||
protected:
|
protected:
|
||||||
static inline TaskLoop*& currentLoopStorage() noexcept;
|
static inline TaskLoop*& currentLoopStorage() noexcept;
|
||||||
template<typename TResult>
|
template<typename TResult>
|
||||||
@ -502,8 +508,8 @@ public: // TaskLoop implementation
|
|||||||
|
|
||||||
public: // public interface
|
public: // public interface
|
||||||
[[nodiscard]] constexpr bool empty() const noexcept { return tasks_.empty() && newTasks_.empty(); }
|
[[nodiscard]] constexpr bool empty() const noexcept { return tasks_.empty() && newTasks_.empty(); }
|
||||||
inline CanContinue tick() noexcept;
|
inline CanContinue tick();
|
||||||
inline void runUntilDone(IgnoreWaiting ignoreWaiting = IgnoreWaiting::NO) noexcept;
|
inline void runUntilDone(IgnoreWaiting ignoreWaiting = IgnoreWaiting::NO);
|
||||||
private:
|
private:
|
||||||
inline void assertCorrectThread() { MIJIN_ASSERT(threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id(), "Unsafe to TaskLoop from different thread!"); }
|
inline void assertCorrectThread() { MIJIN_ASSERT(threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id(), "Unsafe to TaskLoop from different thread!"); }
|
||||||
};
|
};
|
||||||
@ -582,7 +588,7 @@ inline FuturePtr<TResult> TaskLoop::addTask(TaskBase<TResult> task, TaskHandle*
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TaskStatus TaskLoop::tickTask(StoredTask& task) noexcept
|
inline TaskStatus TaskLoop::tickTask(StoredTask& task)
|
||||||
{
|
{
|
||||||
TaskStatus status = {};
|
TaskStatus status = {};
|
||||||
impl::gCurrentTask = &task;
|
impl::gCurrentTask = &task;
|
||||||
@ -596,6 +602,23 @@ inline TaskStatus TaskLoop::tickTask(StoredTask& task) noexcept
|
|||||||
|
|
||||||
if (task.task && task.task->exception())
|
if (task.task && task.task->exception())
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::rethrow_exception(task.task->exception());
|
||||||
|
}
|
||||||
|
catch(impl::TaskCancelled&) {} // ignore those
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
if (uncaughtExceptionHandler_)
|
||||||
|
{
|
||||||
|
uncaughtExceptionHandler_(std::current_exception());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: handle the exception somehow, others may be waiting
|
// TODO: handle the exception somehow, others may be waiting
|
||||||
return TaskStatus::FINISHED;
|
return TaskStatus::FINISHED;
|
||||||
}
|
}
|
||||||
@ -644,7 +667,7 @@ inline std::suspend_always switchContext(TaskLoop& taskLoop)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto SimpleTaskLoop::tick() noexcept -> CanContinue
|
inline auto SimpleTaskLoop::tick() -> CanContinue
|
||||||
{
|
{
|
||||||
// set current taskloop
|
// set current taskloop
|
||||||
MIJIN_ASSERT(currentLoopStorage() == nullptr, "Trying to tick a loop from a coroutine, this is not supported.");
|
MIJIN_ASSERT(currentLoopStorage() == nullptr, "Trying to tick a loop from a coroutine, this is not supported.");
|
||||||
@ -705,7 +728,7 @@ inline auto SimpleTaskLoop::tick() noexcept -> CanContinue
|
|||||||
return canContinue;
|
return canContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SimpleTaskLoop::runUntilDone(IgnoreWaiting ignoreWaiting) noexcept
|
inline void SimpleTaskLoop::runUntilDone(IgnoreWaiting ignoreWaiting)
|
||||||
{
|
{
|
||||||
while (!tasks_.empty() || !newTasks_.empty())
|
while (!tasks_.empty() || !newTasks_.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user