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 { ...@@ -199,7 +199,8 @@ class abstract_actor : public abstract_channel {
has_timeout_flag = 0x02, // mixin::single_timeout has_timeout_flag = 0x02, // mixin::single_timeout
is_registered_flag = 0x04, // no_resume, resumable, and scoped_actor is_registered_flag = 0x04, // no_resume, resumable, and scoped_actor
is_initialized_flag = 0x08, // event-based actors 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) { inline void set_flag(bool enable_flag, actor_state_flag mask) {
......
...@@ -47,6 +47,8 @@ class blocking_actor ...@@ -47,6 +47,8 @@ class blocking_actor
public: public:
class functor_based; class functor_based;
blocking_actor();
/************************************************************************** /**************************************************************************
* utility stuff and receive() member function family * * utility stuff and receive() member function family *
**************************************************************************/ **************************************************************************/
...@@ -200,12 +202,6 @@ class blocking_actor ...@@ -200,12 +202,6 @@ class blocking_actor
*/ */
virtual void act() = 0; 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 */ /** @cond PRIVATE */
// required from invoke_policy; unused in blocking actors // required from invoke_policy; unused in blocking actors
......
...@@ -264,13 +264,14 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> { ...@@ -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 * 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 * exit message to all of its linked actors, sets its state to exited
* and finishes execution. * 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 * @warning This member function throws immediately in thread-based actors
* that do not use the behavior stack, i.e., actors that use * that do not use the behavior stack, i.e., actors that use
* blocking API calls such as {@link receive()}. * 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. * Checks whether this actor traps exit messages.
...@@ -316,6 +317,14 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> { ...@@ -316,6 +317,14 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
set_flag(value, is_running_flag); 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. * Returns the last message that was dequeued from the actor's mailbox.
* @warning Only set during callback invocation. * @warning Only set during callback invocation.
......
...@@ -27,13 +27,12 @@ ...@@ -27,13 +27,12 @@
namespace caf { namespace caf {
void blocking_actor::await_all_other_actors_done() { blocking_actor::blocking_actor() {
detail::singletons::get_actor_registry()->await_running_count_equal(1); is_blocking(true);
} }
void blocking_actor::quit(uint32_t reason) { void blocking_actor::await_all_other_actors_done() {
planned_exit_reason(reason); detail::singletons::get_actor_registry()->await_running_count_equal(1);
throw actor_exited(reason);
} }
void blocking_actor::functor_based::create(blocking_actor*, act_fun fun) { void blocking_actor::functor_based::create(blocking_actor*, act_fun fun) {
......
...@@ -162,6 +162,10 @@ void local_actor::cleanup(uint32_t reason) { ...@@ -162,6 +162,10 @@ void local_actor::cleanup(uint32_t reason) {
void local_actor::quit(uint32_t reason) { void local_actor::quit(uint32_t reason) {
CAF_LOG_TRACE("reason = " << reason << ", class " CAF_LOG_TRACE("reason = " << reason << ", class "
<< detail::demangle(typeid(*this))); << detail::demangle(typeid(*this)));
planned_exit_reason(reason);
if (is_blocking()) {
throw actor_exited(reason);
}
if (reason == exit_reason::unallowed_function_call) { if (reason == exit_reason::unallowed_function_call) {
// this is the only reason that causes an exception // this is the only reason that causes an exception
cleanup(reason); cleanup(reason);
...@@ -174,7 +178,6 @@ void local_actor::quit(uint32_t reason) { ...@@ -174,7 +178,6 @@ void local_actor::quit(uint32_t reason) {
"to use receive()\n"; "to use receive()\n";
throw actor_exited(reason); throw actor_exited(reason);
} }
planned_exit_reason(reason);
} }
message_id local_actor::timed_sync_send_tuple_impl(message_priority mp, 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