Propagate timer exceptions to the main thread

This commit is contained in:
King_DuckZ 2020-08-15 22:52:20 +01:00
parent 85c240b53d
commit f648e3a8a2
7 changed files with 35 additions and 6 deletions

View file

@ -42,4 +42,8 @@ void Event::on_loop_stopping_local() noexcept {
}
}
void Event::set_exception (std::exception_ptr ptr) {
m_eventia->set_exception(ptr);
}
} //namespace eve

View file

@ -17,6 +17,8 @@
#pragma once
#include <exception>
namespace eve {
class Context;
@ -28,6 +30,7 @@ protected:
virtual ~Event() noexcept;
virtual void on_loop_stopping() noexcept = 0;
void set_exception (std::exception_ptr ptr);
private:
void on_loop_stopping_local() noexcept;

View file

@ -26,6 +26,7 @@
#include <utility>
#include <future>
#include <stdexcept>
#include <atomic>
namespace eve {
@ -51,12 +52,14 @@ struct Eventia::LocalData {
Context context;
std::promise<void> loop_end_promise;
std::future<void> loop_end;
std::atomic_bool mark_loop_end;
};
Eventia::LocalData::LocalData(Eventia* eventia) :
loop(ev::AUTO),
context{ &loop, &ev_mutex, &async, eventia },
loop_end(loop_end_promise.get_future())
loop_end(loop_end_promise.get_future()),
mark_loop_end(true)
{
}
@ -86,12 +89,14 @@ Eventia::~Eventia() noexcept {
std::function<void()> Eventia::event_functor() {
return std::function<void()>([this]() {
m_local->mark_loop_end = true;
std::unique_lock<std::mutex> lock(m_local->ev_mutex);
m_local->loop.run(0);
#if !defined(NDEBUG)
std::cout << "ev loop stopped\n";
#endif
m_local->loop_end_promise.set_value();
if (m_local->mark_loop_end)
m_local->loop_end_promise.set_value();
});
}
@ -124,6 +129,12 @@ void Eventia::unlock_mutex_libev() noexcept {
m_local->ev_mutex.unlock();
}
void Eventia::set_exception (std::exception_ptr ptr) {
m_local->mark_loop_end = false;
this->stop();
m_local->loop_end_promise.set_exception(ptr);
}
const Context& Eventia::context() {
return m_local->context;
}

View file

@ -19,6 +19,7 @@
#include <memory>
#include <functional>
#include <exception>
namespace eve {
@ -47,6 +48,7 @@ private:
void lock_mutex_libev() noexcept;
void unlock_mutex_libev() noexcept;
void set_exception (std::exception_ptr ptr);
const Context& context();
unsigned int register_stop_callback (std::function<void()>&& cb);

View file

@ -24,7 +24,7 @@ namespace eve {
class Context;
class Signal : public Event {
class Signal : private Event {
public:
Signal() = delete;
Signal(Signal&&) = default;
@ -35,6 +35,8 @@ public:
virtual void on_signal() = 0;
protected:
using Event::set_exception;
private:
struct LocalData;

View file

@ -36,6 +36,7 @@ public:
protected:
void set_timer (double delay);
using Event::set_exception;
private:
struct LocalData;

View file

@ -18,6 +18,7 @@
#pragma once
#include "timer_base.hpp"
#include <exception>
namespace oro {
class Api;
@ -54,9 +55,14 @@ inline TimerOroApi<Method>::TimerOroApi (
template<auto Method>
inline void TimerOroApi<Method>::fetch_data() {
auto results = (oro_api().*Method)();
set_next_timer(results.first);
this->update_db(results.second);
try {
auto results = (oro_api().*Method)();
set_next_timer(results.first);
this->update_db(results.second);
}
catch (...) {
this->set_exception(std::current_exception());
}
}
} //namespace duck