Commit 57257de9 authored by Dominik Charousset's avatar Dominik Charousset

Guard handler calls, relates #528

parent 774c65b8
...@@ -343,6 +343,36 @@ public: ...@@ -343,6 +343,36 @@ public:
protected: protected:
/// @cond PRIVATE /// @cond PRIVATE
/// Utility function that swaps `f` into a temporary before calling it
/// and restoring `f` only if it has not been replaced by the user.
template <class F, class... Ts>
auto call_handler(F& f, Ts&&... xs)
-> typename std::enable_if<
!std::is_same<decltype(f(std::forward<Ts>(xs)...)), void>::value,
decltype(f(std::forward<Ts>(xs)...))
>::type {
using std::swap;
F g;
swap(f, g);
auto res = g(std::forward<Ts>(xs)...);
if (!f)
swap(g, f);
return res;
}
template <class F, class... Ts>
auto call_handler(F& f, Ts&&... xs)
-> typename std::enable_if<
std::is_same<decltype(f(std::forward<Ts>(xs)...)), void>::value
>::type {
using std::swap;
F g;
swap(f, g);
g(std::forward<Ts>(xs)...);
if (!f)
swap(g, f);
}
// -- member variables ------------------------------------------------------- // -- member variables -------------------------------------------------------
/// Stores user-defined callbacks for message handling. /// Stores user-defined callbacks for message handling.
......
...@@ -356,18 +356,18 @@ scheduled_actor::categorize(mailbox_element& x) { ...@@ -356,18 +356,18 @@ scheduled_actor::categorize(mailbox_element& x) {
fail_state_ = std::move(em.reason); fail_state_ = std::move(em.reason);
setf(is_terminated_flag); setf(is_terminated_flag);
} else { } else {
exit_handler_(this, em); call_handler(exit_handler_, this, em);
} }
return message_category::internal; return message_category::internal;
} }
case make_type_token<down_msg>(): { case make_type_token<down_msg>(): {
auto dm = content.move_if_unshared<down_msg>(0); auto dm = content.move_if_unshared<down_msg>(0);
down_handler_(this, dm); call_handler(down_handler_, this, dm);
return message_category::internal; return message_category::internal;
} }
case make_type_token<error>(): { case make_type_token<error>(): {
auto err = content.move_if_unshared<error>(0); auto err = content.move_if_unshared<error>(0);
error_handler_(this, err); call_handler(error_handler_, this, err);
return message_category::internal; return message_category::internal;
} }
default: default:
...@@ -436,7 +436,7 @@ invoke_message_result scheduled_actor::consume(mailbox_element& x) { ...@@ -436,7 +436,7 @@ invoke_message_result scheduled_actor::consume(mailbox_element& x) {
setf(has_timeout_flag); setf(has_timeout_flag);
}); });
auto call_default_handler = [&] { auto call_default_handler = [&] {
auto sres = default_handler_(this, x); auto sres = call_handler(default_handler_, this, x);
switch (sres.flag) { switch (sres.flag) {
default: default:
break; break;
...@@ -529,7 +529,7 @@ bool scheduled_actor::activate(execution_unit* ctx) { ...@@ -529,7 +529,7 @@ bool scheduled_actor::activate(execution_unit* ctx) {
catch (...) { catch (...) {
CAF_LOG_ERROR("actor died during initialization"); CAF_LOG_ERROR("actor died during initialization");
auto eptr = std::current_exception(); auto eptr = std::current_exception();
quit(exception_handler_(this, eptr)); quit(call_handler(exception_handler_, this, eptr));
finalize(); finalize();
return false; return false;
} }
...@@ -572,12 +572,12 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result { ...@@ -572,12 +572,12 @@ auto scheduled_actor::reactivate(mailbox_element& x) -> activation_result {
CAF_LOG_INFO("actor died because of an exception, what: " << e.what()); CAF_LOG_INFO("actor died because of an exception, what: " << e.what());
static_cast<void>(e); // keep compiler happy when not logging static_cast<void>(e); // keep compiler happy when not logging
auto eptr = std::current_exception(); auto eptr = std::current_exception();
quit(exception_handler_(this, eptr)); quit(call_handler(exception_handler_, this, eptr));
} }
catch (...) { catch (...) {
CAF_LOG_INFO("actor died because of an unknown exception"); CAF_LOG_INFO("actor died because of an unknown exception");
auto eptr = std::current_exception(); auto eptr = std::current_exception();
quit(exception_handler_(this, eptr)); quit(call_handler(exception_handler_, this, eptr));
} }
finalize(); finalize();
return activation_result::terminated; return activation_result::terminated;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment