Commit 7f446d8c authored by Dominik Charousset's avatar Dominik Charousset

Remove `virtual` keyword from `quit`

Use an if-statement in `local_actor` to determine whether or not this actor is
blocking. This allows us to make the function non-virtual since its only
overload existed in `blocking_actor`. Relates #180.
parent 55fa3e33
......@@ -199,7 +199,8 @@ class abstract_actor : public abstract_channel {
has_timeout_flag = 0x02, // mixin::single_timeout
is_registered_flag = 0x04, // no_resume, resumable, and scoped_actor
is_initialized_flag = 0x08, // event-based actors
is_running_flag = 0x10 // broker
is_running_flag = 0x10, // broker
is_blocking_flag = 0x20 // blocking_actor
};
inline void set_flag(bool enable_flag, actor_state_flag mask) {
......
......@@ -47,6 +47,8 @@ class blocking_actor
public:
class functor_based;
blocking_actor();
/**************************************************************************
* utility stuff and receive() member function family *
**************************************************************************/
......@@ -200,12 +202,6 @@ class blocking_actor
*/
virtual void act() = 0;
/**
* Unwinds the stack by throwing an actor_exited exception.
* @throws actor_exited
*/
virtual void quit(uint32_t reason = exit_reason::normal);
/** @cond PRIVATE */
// required from invoke_policy; unused in blocking actors
......
......@@ -264,13 +264,14 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
* If `on_exit()` did not set a new behavior, the actor sends an
* exit message to all of its linked actors, sets its state to exited
* and finishes execution.
* @note Throws {@link actor_exited} to unwind the stack
* (only) when called in detached actors.
*
* In case this actor uses the blocking API, this member function unwinds
* the stack by throwing an `actor_exited` exception.
* @warning This member function throws immediately in thread-based actors
* that do not use the behavior stack, i.e., actors that use
* blocking API calls such as {@link receive()}.
*/
virtual void quit(uint32_t reason = exit_reason::normal);
void quit(uint32_t reason = exit_reason::normal);
/**
* Checks whether this actor traps exit messages.
......@@ -316,6 +317,14 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
set_flag(value, is_running_flag);
}
inline bool is_blocking() const {
return get_flag(is_blocking_flag);
}
inline void is_blocking(bool value) {
set_flag(value, is_blocking_flag);
}
/**
* Returns the last message that was dequeued from the actor's mailbox.
* @warning Only set during callback invocation.
......
......@@ -27,13 +27,12 @@
namespace caf {
void blocking_actor::await_all_other_actors_done() {
detail::singletons::get_actor_registry()->await_running_count_equal(1);
blocking_actor::blocking_actor() {
is_blocking(true);
}
void blocking_actor::quit(uint32_t reason) {
planned_exit_reason(reason);
throw actor_exited(reason);
void blocking_actor::await_all_other_actors_done() {
detail::singletons::get_actor_registry()->await_running_count_equal(1);
}
void blocking_actor::functor_based::create(blocking_actor*, act_fun fun) {
......
......@@ -162,6 +162,10 @@ void local_actor::cleanup(uint32_t reason) {
void local_actor::quit(uint32_t reason) {
CAF_LOG_TRACE("reason = " << reason << ", class "
<< detail::demangle(typeid(*this)));
planned_exit_reason(reason);
if (is_blocking()) {
throw actor_exited(reason);
}
if (reason == exit_reason::unallowed_function_call) {
// this is the only reason that causes an exception
cleanup(reason);
......@@ -174,7 +178,6 @@ void local_actor::quit(uint32_t reason) {
"to use receive()\n";
throw actor_exited(reason);
}
planned_exit_reason(reason);
}
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp,
......
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