static message_id apply(message_id x) { CAF_IGNORE_UNUSED(x); auto result = make_message_id(message_id::upstream_message_category << message_id::category_offset); CAF_ASSERT(x.is_async() || x == result); return result; }
bool monitorable_actor::cleanup(error&& reason, execution_unit* host) { CAF_LOG_TRACE(CAF_ARG(reason)); attachable_ptr head; bool set_fail_state = exclusive_critical_section([&]() -> bool { if (!getf(is_cleaned_up_flag)) { // local actors pass fail_state_ as first argument if (&fail_state_ != &reason) fail_state_ = std::move(reason); attachables_head_.swap(head); flags(flags() | is_terminated_flag | is_cleaned_up_flag); on_cleanup(); return true; } return false; }); if (!set_fail_state) return false; CAF_LOG_DEBUG("cleanup" << CAF_ARG(id()) << CAF_ARG(node()) << CAF_ARG(reason)); // send exit messages for (attachable* i = head.get(); i != nullptr; i = i->next.get()) i->actor_exited(reason, host); // tell printer to purge its state for us if we ever used aout() if (getf(abstract_actor::has_used_aout_flag)) { auto pr = home_system().scheduler().printer(); pr->enqueue(make_mailbox_element(nullptr, make_message_id(), {}, delete_atom::value, id()), nullptr); } return true; }
void monitorable_actor::add_link(abstract_actor* x) { // Add backlink on `x` first and add the local attachable only on success. CAF_LOG_TRACE(CAF_ARG(x)); CAF_ASSERT(x != nullptr); error fail_state; bool send_exit_immediately = false; auto tmp = default_attachable::make_link(address(), x->address()); joined_exclusive_critical_section(this, x, [&] { if (getf(is_terminated_flag)) { fail_state = fail_state_; send_exit_immediately = true; } else if (x->add_backlink(this)) { attach_impl(tmp); } }); if (send_exit_immediately) x->enqueue(nullptr, make_message_id(), make_message(exit_msg{address(), fail_state}), nullptr); }
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, make_message_id(), make_message(exit_msg{address(), fail_state}), nullptr); return success; }