Commit d016fb80 authored by Dominik Charousset's avatar Dominik Charousset

Combine actor bool fields to a single flags field

parent 10a49baa
......@@ -173,6 +173,27 @@ class abstract_actor : public abstract_channel {
*/
virtual std::set<std::string> message_types() const;
enum actor_state_flag {
// used by ...
trap_exit_flag = 0x01, // local_actor
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
};
inline void set_flag(bool enable_flag, actor_state_flag mask) {
if (enable_flag) {
m_flags |= static_cast<int>(mask);
} else {
m_flags &= ~static_cast<int>(mask);
}
}
inline bool get_flag(actor_state_flag mask) const {
return static_cast<bool>(m_flags & static_cast<int>(mask));
}
protected:
/**
* Creates a non-proxy instance.
......@@ -221,13 +242,9 @@ class abstract_actor : public abstract_channel {
m_host = new_host;
}
private:
// cannot be changed after construction
const actor_id m_id;
// you're either a proxy or you're not
const bool m_is_proxy;
// initially exit_reason::not_exited
std::atomic<uint32_t> m_exit_reason;
......@@ -242,6 +259,9 @@ class abstract_actor : public abstract_channel {
// identifies the execution unit this actor is currently executed by
execution_unit* m_host;
// stores several actor-related flags
int m_flags;
};
} // namespace caf
......
......@@ -44,11 +44,13 @@ class proper_actor_base : public Policies::resume_policy::template
public:
template <class... Ts>
proper_actor_base(Ts&&... args) : super(std::forward<Ts>(args)...) {
CAF_REQUIRE(this->m_hidden == true);
CAF_REQUIRE(this->is_registered() == false);
}
// grant access to the actor's mailbox
typename Base::mailbox_type& mailbox() { return this->m_mailbox; }
typename Base::mailbox_type& mailbox() {
return this->m_mailbox;
}
// member functions from scheduling policy
......@@ -65,9 +67,9 @@ class proper_actor_base : public Policies::resume_policy::template
scheduling_policy().enqueue(dptr(), sender, mid, msg, eu);
}
inline void launch(bool is_hidden, execution_unit* host) {
inline void launch(bool hidden, execution_unit* host) {
CAF_LOG_TRACE("");
this->hidden(is_hidden);
this->is_registered(!hidden);
this->scheduling_policy().launch(this, host);
}
......@@ -141,16 +143,6 @@ class proper_actor_base : public Policies::resume_policy::template
awaited_response);
}
inline bool hidden() const {
return this->m_hidden;
}
void cleanup(uint32_t reason) override {
CAF_LOG_TRACE(CAF_ARG(reason));
if (!hidden()) detail::singletons::get_actor_registry()->dec_running();
super::cleanup(reason);
}
protected:
inline typename Policies::scheduling_policy& scheduling_policy() {
return m_policies.get_scheduling_policy();
......@@ -172,16 +164,6 @@ class proper_actor_base : public Policies::resume_policy::template
return static_cast<Derived*>(this);
}
inline void hidden(bool value) {
if (this->m_hidden == value) return;
if (value) {
detail::singletons::get_actor_registry()->dec_running();
} else {
detail::singletons::get_actor_registry()->inc_running();
}
this->m_hidden = value;
}
private:
Policies m_policies;
};
......
......@@ -55,7 +55,7 @@ class event_based_actor
*/
void forward_to(const actor& whom);
event_based_actor();
event_based_actor() = default;
~event_based_actor();
......@@ -66,8 +66,6 @@ class event_based_actor
* Returns the initial actor behavior.
*/
virtual behavior make_behavior() = 0;
bool m_initialized;
};
class event_based_actor::functor_based : public extend<event_based_actor>::
......
......@@ -281,14 +281,44 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
* Checks whether this actor traps exit messages.
*/
inline bool trap_exit() const {
return m_trap_exit;
return get_flag(trap_exit_flag);
}
/**
* Enables or disables trapping of exit messages.
*/
inline void trap_exit(bool new_value) {
m_trap_exit = new_value;
inline void trap_exit(bool value) {
set_flag(value, trap_exit_flag);
}
inline bool has_timeout() const {
return get_flag(has_timeout_flag);
}
inline void has_timeout(bool value) {
set_flag(value, has_timeout_flag);
}
inline bool is_registered() const {
return get_flag(is_registered_flag);
}
void is_registered(bool value);
inline bool is_initialized() const {
return get_flag(is_initialized_flag);
}
inline void is_initialized(bool value) {
set_flag(value, is_initialized_flag);
}
inline bool is_running() const {
return get_flag(is_running_flag);
}
inline void is_running(bool value) {
set_flag(value, is_running_flag);
}
/**
......@@ -490,9 +520,6 @@ class local_actor : public extend<abstract_actor>::with<mixin::memory_cached> {
return mailbox_element::create(std::forward<Ts>(args)...);
}
// true if this actor receives EXIT messages as ordinary messages
bool m_trap_exit;
// identifies the ID of the last sent synchronous request
message_id m_last_request_id;
......
......@@ -111,7 +111,7 @@ class behavior_stack_based_impl : public single_timeout<Base, Subtype> {
// request next timeout if behavior stack is not empty
// and timeout handler did not set a new timeout, e.g.,
// by calling become()
if (!this->has_active_timeout() && has_behavior()) {
if (!this->has_timeout() && has_behavior()) {
this->request_timeout(get_behavior().timeout());
}
}
......
......@@ -32,22 +32,21 @@ namespace mixin {
*/
template <class Base, class Subtype>
class single_timeout : public Base {
using super = Base;
public:
using super = Base;
using combined_type = single_timeout;
template <class... Ts>
single_timeout(Ts&&... args)
: super(std::forward<Ts>(args)...)
, m_has_timeout(false)
, m_timeout_id(0) {}
: super(std::forward<Ts>(args)...),
m_timeout_id(0) {
// nop
}
void request_timeout(const duration& d) {
if (d.valid()) {
m_has_timeout = true;
this->has_timeout(true);
auto tid = ++m_timeout_id;
auto msg = make_message(timeout_msg{tid});
if (d.is_zero()) {
......@@ -57,26 +56,23 @@ class single_timeout : public Base {
} else
this->delayed_send_tuple(this, d, std::move(msg));
} else
m_has_timeout = false;
this->has_timeout(false);
}
inline bool waits_for_timeout(uint32_t timeout_id) const {
return m_has_timeout && m_timeout_id == timeout_id;
bool waits_for_timeout(uint32_t timeout_id) const {
return this->has_timeout() && m_timeout_id == timeout_id;
}
inline bool is_active_timeout(uint32_t tid) const {
bool is_active_timeout(uint32_t tid) const {
return waits_for_timeout(tid);
}
inline bool has_active_timeout() const { return m_has_timeout; }
inline void reset_timeout() { m_has_timeout = false; }
void reset_timeout() {
this->has_timeout(false);
}
protected:
bool m_has_timeout;
uint32_t m_timeout_id;
};
} // namespace mixin
......
......@@ -93,8 +93,8 @@ class event_based_resume {
|| (!d->bhvr_stack().empty()
&& d->planned_exit_reason() == exit_reason::not_exited));
try {
if (!d->m_initialized) {
d->m_initialized = true;
if (!d->is_initialized()) {
d->is_initialized(true);
auto bhvr = d->make_behavior();
if (bhvr) {
// make_behavior() did return a behavior instead of using become()
......
......@@ -16,7 +16,7 @@ class no_resume {
template <class Base, class Derived>
struct mixin : Base {
template <class... Ts>
mixin(Ts&&... args) : Base(std::forward<Ts>(args)...), m_hidden(true) {
mixin(Ts&&... args) : Base(std::forward<Ts>(args)...) {
// nop
}
......@@ -50,8 +50,6 @@ class no_resume {
this->cleanup(this->planned_exit_reason());
return resumable::done;
}
bool m_hidden;
};
template <class Actor>
......
......@@ -39,7 +39,7 @@ class resumable {
shutdown_execution_unit
};
resumable();
resumable() = default;
virtual ~resumable();
......@@ -58,9 +58,6 @@ class resumable {
* or needs to be re-scheduled later.
*/
virtual resume_result resume(execution_unit*, size_t max_throughput) = 0;
protected:
bool m_hidden;
};
} // namespace caf
......
......@@ -29,9 +29,7 @@ namespace caf {
* A scoped handle to a blocking actor.
*/
class scoped_actor {
public:
scoped_actor();
scoped_actor(const scoped_actor&) = delete;
......@@ -40,28 +38,38 @@ class scoped_actor {
~scoped_actor();
inline blocking_actor* operator->() const { return m_self.get(); }
inline blocking_actor* operator->() const {
return m_self.get();
}
inline blocking_actor& operator*() const { return *m_self; }
inline blocking_actor& operator*() const {
return *m_self;
}
inline blocking_actor* get() const { return m_self.get(); }
inline blocking_actor* get() const {
return m_self.get();
}
operator channel() const { return get(); }
inline operator channel() const {
return get();
}
operator actor() const { return get(); }
inline operator actor() const {
return get();
}
operator actor_addr() const { return get()->address(); }
inline operator actor_addr() const {
return get()->address();
}
inline actor_addr address() const { return get()->address(); }
inline actor_addr address() const {
return get()->address();
}
private:
void init(bool hide_actor);
bool m_hidden;
actor_id m_prev; // used for logging/debugging purposes only
intrusive_ptr<blocking_actor> m_self;
};
} // namespace caf
......
......@@ -80,10 +80,7 @@ class single_timeout : public Base {
}
protected:
bool m_has_timeout;
std::uint32_t m_timeout_id;
};
} // namespace caf
......
......@@ -44,10 +44,6 @@ class typed_event_based_actor : public
mixin::behavior_stack_based<typed_behavior<Rs...>>::template impl,
mixin::sync_sender<nonblocking_response_handle_tag>::template impl> {
public:
typed_event_based_actor() : m_initialized(false) {
// nop
}
using signatures = detail::type_list<Rs...>;
using behavior_type = typed_behavior<Rs...>;
......@@ -58,7 +54,6 @@ class typed_event_based_actor : public
protected:
virtual behavior_type make_behavior() = 0;
bool m_initialized;
};
} // namespace caf
......
......@@ -49,18 +49,18 @@ using guard_type = std::unique_lock<std::mutex>;
abstract_actor::abstract_actor(actor_id aid, node_id nid)
: super(std::move(nid)),
m_id(aid),
m_is_proxy(true),
m_exit_reason(exit_reason::not_exited),
m_host(nullptr) {
m_host(nullptr),
m_flags(0) {
// nop
}
abstract_actor::abstract_actor()
: super(detail::singletons::get_node_id()),
m_id(detail::singletons::get_actor_registry()->next_id()),
m_is_proxy(false),
m_exit_reason(exit_reason::not_exited),
m_host(nullptr) {
m_host(nullptr),
m_flags(0) {
// nop
}
......@@ -180,8 +180,7 @@ actor_addr abstract_actor::address() const {
void abstract_actor::cleanup(uint32_t reason) {
// log as 'actor'
CAF_LOGM_TRACE("caf::actor", CAF_ARG(m_id) << ", " << CAF_ARG(reason) << ", "
<< CAF_ARG(m_is_proxy));
CAF_LOGM_TRACE("caf::actor", CAF_ARG(m_id) << ", " << CAF_ARG(reason));
CAF_REQUIRE(reason != exit_reason::not_exited);
// move everyhting out of the critical section before processing it
decltype(m_links) mlinks;
......
......@@ -25,10 +25,6 @@
namespace caf {
event_based_actor::event_based_actor() : m_initialized(false) {
// nop
}
event_based_actor::~event_based_actor() {
// nop
}
......
......@@ -60,8 +60,7 @@ class down_observer : public attachable {
} // namespace <anonymous>
local_actor::local_actor()
: m_trap_exit(false),
m_dummy_node(),
: m_dummy_node(),
m_current_node(&m_dummy_node),
m_planned_exit_reason(exit_reason::not_exited) {
// nop
......@@ -178,6 +177,8 @@ void local_actor::cleanup(uint32_t reason) {
CAF_LOG_TRACE(CAF_ARG(reason));
m_subscriptions.clear();
super::cleanup(reason);
// tell registry we're done
is_registered(false);
}
void local_actor::quit(uint32_t reason) {
......@@ -235,4 +236,16 @@ message_id local_actor::sync_send_tuple_impl(message_priority mp,
return nri.response_id();
}
void local_actor::is_registered(bool value) {
if (is_registered() == value) {
return;
}
if (value) {
detail::singletons::get_actor_registry()->inc_running();
} else {
detail::singletons::get_actor_registry()->dec_running();
}
set_flag(value, is_registered_flag);
}
} // namespace caf
......@@ -21,10 +21,6 @@
namespace caf {
resumable::resumable() : m_hidden(true) {
// nop
}
resumable::~resumable() {
// nop
}
......
......@@ -47,10 +47,9 @@ blocking_actor* alloc() {
} // namespace <anonymous>
void scoped_actor::init(bool hide_actor) {
m_hidden = hide_actor;
m_self.reset(alloc());
if (!m_hidden) {
detail::singletons::get_actor_registry()->inc_running();
m_self->is_registered(!hide_actor);
if (!hide_actor) {
m_prev = CAF_SET_AID(m_self->id());
}
}
......@@ -64,12 +63,11 @@ scoped_actor::scoped_actor(bool hide_actor) {
}
scoped_actor::~scoped_actor() {
auto r = m_self->planned_exit_reason();
m_self->cleanup(r == exit_reason::not_exited ? exit_reason::normal : r);
if (!m_hidden) {
detail::singletons::get_actor_registry()->dec_running();
if (m_self->is_registered()) {
CAF_SET_AID(m_prev);
}
auto r = m_self->planned_exit_reason();
m_self->cleanup(r == exit_reason::not_exited ? exit_reason::normal : r);
}
} // namespace caf
......@@ -317,7 +317,9 @@ class broker : public extend<local_actor>::
};
intrusive_ptr<impl> ptr{new impl{this, std::move(sock)}};
m_doormen.insert(std::make_pair(ptr->hdl(), ptr));
if (initialized()) ptr->launch();
if (is_initialized()) {
ptr->launch();
}
return ptr->hdl();
}
......@@ -383,8 +385,6 @@ class broker : public extend<local_actor>::
using doorman_pointer = intrusive_ptr<doorman>;
bool initialized() const;
virtual behavior make_behavior() = 0;
/** @endcond */
......@@ -428,12 +428,6 @@ class broker : public extend<local_actor>::
policy::not_prioritizing m_priority_policy;
policy::sequential_invoke m_invoke_policy;
bool m_initialized;
bool m_hidden;
bool m_running;
middleman& m_mm;
};
......
......@@ -54,7 +54,7 @@ void broker::servant::disconnect() {
m_disconnected = true;
remove_from_broker();
if (m_broker->exit_reason() == exit_reason::not_exited) {
if (m_broker->m_running) {
if (m_broker->is_running()) {
CAF_LOG_DEBUG("broker is running, push message to cache");
// push this message to the cache to make sure we
// don't have interleaved message handlers
......@@ -164,8 +164,8 @@ class broker::continuation {
void broker::invoke_message(const actor_addr& sender, message_id mid,
message& msg) {
CAF_LOG_TRACE(CAF_TARG(msg, to_string));
m_running = true;
auto sg = detail::make_scope_guard([=] { m_running = false; });
is_running(true);
auto sg = detail::make_scope_guard([=] { is_running(false); });
if (planned_exit_reason() != exit_reason::not_exited
|| bhvr_stack().empty()) {
CAF_LOG_DEBUG("actor already finished execution"
......@@ -268,15 +268,7 @@ void broker::enqueue(const actor_addr& sender, message_id mid, message msg,
mid, std::move(msg)});
}
bool broker::initialized() const {
return m_initialized;
}
broker::broker()
: m_initialized(false),
m_hidden(true),
m_running(false),
m_mm(*middleman::instance()) {
broker::broker() : m_mm(*middleman::instance()) {
// nop
}
......@@ -284,21 +276,16 @@ void broker::cleanup(uint32_t reason) {
CAF_LOG_TRACE(CAF_ARG(reason));
close_all();
super::cleanup(reason);
if (!m_hidden){
detail::singletons::get_actor_registry()->dec_running();
}
}
void broker::launch(bool is_hidden, execution_unit*) {
if (!is_hidden) {
m_hidden = false;
detail::singletons::get_actor_registry()->inc_running();
}
is_registered(!is_hidden);
CAF_PUSH_AID(id());
CAF_LOGF_TRACE("init and launch broker with id " << id());
// we want to make sure initialization is executed in MM context
broker_ptr self = this;
self->become(on(atom("INITMSG")) >> [self] {
self->become(
on(atom("INITMSG")) >> [self] {
CAF_LOGF_TRACE(CAF_MARG(self, get));
self->unbecome();
// launch backends now, because user-defined initialization
......@@ -306,12 +293,14 @@ void broker::launch(bool is_hidden, execution_unit*) {
for (auto& kvp : self->m_doormen) {
kvp.second->launch();
}
self->m_initialized = true;
self->is_initialized(true);
// run user-defined initialization code
auto bhvr = self->make_behavior();
if (bhvr)
if (bhvr) {
self->become(std::move(bhvr));
});
}
}
);
self->enqueue(invalid_actor_addr, message_id::invalid,
make_message(atom("INITMSG")), nullptr);
}
......
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