void monitorable_actor::remove_link(abstract_actor* x) { CAF_LOG_TRACE(CAF_ARG(x)); default_attachable::observe_token tk{x->address(), default_attachable::link}; joined_exclusive_critical_section(this, x, [&] { x->remove_backlink(this); detach_impl(tk, true); }); }
bool abstract_actor::remove_backlink_impl(const actor_addr& other) { CAF_LOG_TRACE(CAF_TSARG(other)); default_attachable::observe_token tk{other, default_attachable::link}; if (other && other != this) { guard_type guard{mtx_}; return detach_impl(tk, attachables_head_, true) > 0; } return false; }
size_t abstract_actor::detach_impl(const attachable::token& what, attachable_ptr& ptr, bool stop_on_hit, bool dry_run) { CAF_LOGF_TRACE(""); if (! ptr) { CAF_LOGF_DEBUG("invalid ptr"); return 0; } if (ptr->matches(what)) { if (! dry_run) { CAF_LOGF_DEBUG("removed element"); attachable_ptr next; next.swap(ptr->next); ptr.swap(next); } return stop_on_hit ? 1 : 1 + detach_impl(what, ptr, stop_on_hit, dry_run); } return detach_impl(what, ptr->next, stop_on_hit, dry_run); }
void monitorable_actor::unlink_from(const actor_addr& x) { auto ptr = actor_cast<strong_actor_ptr>(x); if (ptr != nullptr) { if (ptr->get() != this) remove_link(ptr->get()); } else { default_attachable::observe_token tk{x, default_attachable::link}; exclusive_critical_section([&] { detach_impl(tk, true); }); } }
void local_actor::join(const group& what) { CAF_LOG_TRACE(CAF_TSARG(what)); if (what == invalid_group) { return; } abstract_group::subscription_token tk{what.ptr()}; std::unique_lock<std::mutex> guard{m_mtx}; if (detach_impl(tk, m_attachables_head, true, true) == 0) { auto ptr = what->subscribe(address()); if (ptr) { attach_impl(ptr); } } }
bool abstract_actor::remove_link_impl(const actor_addr& other) { CAF_LOG_TRACE(CAF_TSARG(other)); if (other == invalid_actor_addr || other == this) { return false; } default_attachable::observe_token tk{other, default_attachable::link}; guard_type guard{mtx_}; // remove_backlink returns true if this actor is linked to other auto ptr = actor_cast<abstract_actor_ptr>(other); if (detach_impl(tk, attachables_head_, true) > 0) { // tell remote side to remove link as well ptr->remove_backlink(address()); return true; } return false; }
bool monitorable_actor::add_backlink(abstract_actor* x) { // Called in an exclusive critical section. CAF_LOG_TRACE(CAF_ARG(x)); CAF_ASSERT(x); error fail_state; bool send_exit_immediately = false; default_attachable::observe_token tk{x->address(), default_attachable::link}; auto tmp = default_attachable::make_link(address(), x->address()); auto success = false; if (getf(is_terminated_flag)) { fail_state = fail_state_; send_exit_immediately = true; } else if (detach_impl(tk, true, true) == 0) { attach_impl(tmp); success = true; } if (send_exit_immediately) x->enqueue(nullptr, invalid_message_id, make_message(exit_msg{address(), fail_state}), nullptr); return success; }
bool abstract_actor::establish_backlink_impl(const actor_addr& other) { CAF_LOG_TRACE(CAF_TSARG(other)); uint32_t reason = exit_reason::not_exited; default_attachable::observe_token tk{other, default_attachable::link}; if (other && other != this) { guard_type guard{mtx_}; reason = exit_reason_; if (reason == exit_reason::not_exited) { if (detach_impl(tk, attachables_head_, true, true) == 0) { auto tmp = default_attachable::make_link(other); attach_impl(tmp); return true; } } } // send exit message without lock if (reason != exit_reason::not_exited) { auto ptr = actor_cast<abstract_actor_ptr>(other); ptr->enqueue(address(), invalid_message_id, make_message(exit_msg{address(), exit_reason()}), host_); } return false; }
size_t abstract_actor::detach(const attachable::token& what) { CAF_LOG_TRACE(""); guard_type guard{mtx_}; return detach_impl(what, attachables_head_); }
size_t monitorable_actor::detach(const attachable::token& what) { CAF_LOG_TRACE(""); std::unique_lock<std::mutex> guard{mtx_}; return detach_impl(what); }
bool monitorable_actor::remove_backlink(abstract_actor* x) { // Called in an exclusive critical section. CAF_LOG_TRACE(CAF_ARG(x)); default_attachable::observe_token tk{x->address(), default_attachable::link}; return detach_impl(tk, true) > 0; }