actor_ptr default_actor_addressing::read(deserializer* source) { CPPA_REQUIRE(source != nullptr); auto cname = source->seek_object(); if (cname == "@0") { CPPA_LOGMF(CPPA_DEBUG, self, "deserialized nullptr"); source->begin_object("@0"); source->end_object(); return nullptr; } else if (cname == "@actor") { process_information::node_id_type nid; source->begin_object(cname); auto aid = source->read<uint32_t>(); auto pid = source->read<uint32_t>(); source->read_raw(process_information::node_id_size, nid.data()); source->end_object(); // local actor? auto pinf = process_information::get(); if (pid == pinf->process_id() && nid == pinf->node_id()) { return get_actor_registry()->get(aid); } else { process_information tmp(pid, nid); return get_or_put(tmp, aid); } } else throw runtime_error("expected type name \"@0\" or \"@actor\"; " "found: " + cname); }
void default_actor_addressing::write(serializer* sink, const actor_ptr& ptr) { CPPA_REQUIRE(sink != nullptr); if (ptr == nullptr) { CPPA_LOGMF(CPPA_DEBUG, self, "serialized nullptr"); sink->begin_object("@0"); sink->end_object(); } else { // local actor? if (!ptr->is_proxy()) { get_actor_registry()->put(ptr->id(), ptr); } auto pinf = m_pinf; if (ptr->is_proxy()) { auto dptr = ptr.downcast<default_actor_proxy>(); if (dptr) pinf = dptr->process_info(); else CPPA_LOGMF(CPPA_ERROR, self, "downcast failed"); } sink->begin_object("@actor"); sink->write_value(ptr->id()); sink->write_value(pinf->process_id()); sink->write_raw(process_information::node_id_size, pinf->node_id().data()); sink->end_object(); } }
void scoped_actor::init(bool hide_actor) { m_hidden = hide_actor; m_self.reset(alloc()); if (!m_hidden) { get_actor_registry()->inc_running(); m_prev = BOOST_ACTOR_SET_AID(m_self->id()); } }
void publish_impl(abstract_actor_ptr ptr, std::unique_ptr<acceptor> aptr) { // begin the scenes, we serialze/deserialize as actor actor whom{raw_access::unsafe_cast(ptr.get())}; CPPA_LOGF_TRACE(CPPA_TARG(whom, to_string) << ", " << CPPA_MARG(aptr, get)); if (!whom) return; get_actor_registry()->put(whom->id(), detail::raw_access::get(whom)); auto mm = get_middleman(); auto addr = whom.address(); auto sigs = whom->interface(); mm->register_acceptor(addr, new peer_acceptor(mm, move(aptr), addr, move(sigs))); }
actor_ptr default_actor_addressing::read(deserializer* source) { CPPA_REQUIRE(source != nullptr); process_information::node_id_type nid; auto aid = source->read<uint32_t>(); auto pid = source->read<uint32_t>(); source->read_raw(process_information::node_id_size, nid.data()); // local actor? auto pinf = process_information::get(); if (aid == 0 && pid == 0) { return nullptr; } else if (pid == pinf->process_id() && nid == pinf->node_id()) { return get_actor_registry()->get(aid); } else { process_information tmp{pid, nid}; return get_or_put(tmp, aid); } }
void thread_pool_scheduler::destroy() { CPPA_LOG_TRACE(""); m_queue.push_back(&m_dummy); CPPA_LOG_DEBUG("join supervisor"); m_supervisor.join(); // make sure job queue is empty, because destructor of m_queue would // otherwise delete elements it shouldn't CPPA_LOG_DEBUG("flush queue"); auto ptr = m_queue.try_pop(); while (ptr != nullptr) { if (ptr != &m_dummy) { /*FIXME bool hidden = ptr->is_hidden(); ptr->deref(); std::atomic_thread_fence(std::memory_order_seq_cst); if (!hidden)*/ get_actor_registry()->dec_running(); } ptr = m_queue.try_pop(); } super::destroy(); }
void operator()() { CPPA_LOG_TRACE(""); detail::cs_thread fself; job_ptr job = nullptr; for (;;) { aggressive(job) || moderate(job) || relaxed(job); CPPA_LOG_DEBUG("dequeued new job"); if (job == m_dummy) { CPPA_LOG_DEBUG("received dummy (quit)"); // dummy of doom received ... m_job_queue->push_back(job); // kill the next guy return; // and say goodbye } if (job->resume(&fself) == resumable::done) { CPPA_LOG_DEBUG("actor is done"); /*FIXME bool hidden = job->is_hidden(); job->deref(); if (!hidden)*/ get_actor_registry()->dec_running(); } job = nullptr; } }
void default_actor_addressing::write(serializer* sink, const actor_ptr& ptr) { CPPA_REQUIRE(sink != nullptr); if (ptr == nullptr) { CPPA_LOG_DEBUG("serialize nullptr"); sink->write_value(static_cast<actor_id>(0)); process_information::serialize_invalid(sink); } else { // local actor? if (!ptr->is_proxy()) { get_actor_registry()->put(ptr->id(), ptr); } auto pinf = m_pinf; if (ptr->is_proxy()) { auto dptr = ptr.downcast<default_actor_proxy>(); if (dptr) pinf = dptr->process_info(); else CPPA_LOG_ERROR("downcast failed"); } sink->write_value(ptr->id()); sink->write_value(pinf->process_id()); sink->write_raw(process_information::node_id_size, pinf->node_id().data()); } }
actor::actor() : m_id(get_actor_registry()->next_id()), m_is_proxy(false) , m_exit_reason(exit_reason::not_exited) { }
abstract_actor_ptr remote_actor_impl(stream_ptr_pair io, string_set expected) { CPPA_LOGF_TRACE("io{" << io.first.get() << ", " << io.second.get() << "}"); auto mm = get_middleman(); auto pinf = mm->node(); std::uint32_t process_id = pinf->process_id(); // throws on error io.second->write(&process_id, sizeof(std::uint32_t)); io.second->write(pinf->host_id().data(), pinf->host_id().size()); // deserialize: actor id, process id, node id, interface actor_id remote_aid; std::uint32_t peer_pid; node_id::host_id_type peer_node_id; std::uint32_t iface_size; std::set<std::string> iface; auto& in = io.first; // -> actor id in->read(&remote_aid, sizeof(actor_id)); // -> process id in->read(&peer_pid, sizeof(std::uint32_t)); // -> node id in->read(peer_node_id.data(), peer_node_id.size()); // -> interface in->read(&iface_size, sizeof(std::uint32_t)); if (iface_size > max_iface_size) { throw std::invalid_argument("Remote actor claims to have more than" +std::to_string(max_iface_size)+ " message types? Someone is trying" " something nasty!"); } std::vector<char> strbuf; for (std::uint32_t i = 0; i < iface_size; ++i) { std::uint32_t str_size; in->read(&str_size, sizeof(std::uint32_t)); if (str_size > max_iface_clause_size) { throw std::invalid_argument("Remote actor claims to have a" " reply_to<...>::with<...> clause with" " more than" +std::to_string(max_iface_clause_size)+ " characters? Someone is" " trying something nasty!"); } strbuf.reserve(str_size + 1); strbuf.resize(str_size); in->read(strbuf.data(), str_size); strbuf.push_back('\0'); iface.insert(std::string{strbuf.data()}); } // deserialization done, check interface if (iface != expected) { auto tostr = [](const std::set<std::string>& what) -> std::string { if (what.empty()) return "actor"; std::string tmp; tmp = "typed_actor<"; auto i = what.begin(); auto e = what.end(); tmp += *i++; while (i != e) tmp += *i++; tmp += ">"; return tmp; }; auto iface_str = tostr(iface); auto expected_str = tostr(expected); if (expected.empty()) { throw std::invalid_argument("expected remote actor to be a " "dynamically typed actor but found " "a strongly typed actor of type " + iface_str); } if (iface.empty()) { throw std::invalid_argument("expected remote actor to be a " "strongly typed actor of type " + expected_str + " but found a dynamically typed actor"); } throw std::invalid_argument("expected remote actor to be a " "strongly typed actor of type " + expected_str + " but found a strongly typed actor of type " + iface_str); } auto pinfptr = make_counted<node_id>(peer_pid, peer_node_id); if (*pinf == *pinfptr) { // this is a local actor, not a remote actor CPPA_LOGF_INFO("remote_actor() called to access a local actor"); auto ptr = get_actor_registry()->get(remote_aid); return ptr; } struct remote_actor_result { remote_actor_result* next; actor value; }; std::mutex qmtx; std::condition_variable qcv; intrusive::single_reader_queue<remote_actor_result> q; mm->run_later([mm, io, pinfptr, remote_aid, &q, &qmtx, &qcv] { CPPA_LOGC_TRACE("cppa", "remote_actor$create_connection", ""); auto pp = mm->get_peer(*pinfptr); CPPA_LOGF_INFO_IF(pp, "connection already exists (re-use old one)"); if (!pp) mm->new_peer(io.first, io.second, pinfptr); auto res = mm->get_namespace().get_or_put(pinfptr, remote_aid); q.synchronized_enqueue(qmtx, qcv, new remote_actor_result{0, res}); }); std::unique_ptr<remote_actor_result> result(q.synchronized_pop(qmtx, qcv)); CPPA_LOGF_DEBUG(CPPA_MARG(result, get)); return raw_access::get(result->value); }
abstract_actor::abstract_actor() : m_id(get_actor_registry()->next_id()), m_is_proxy(false) , m_exit_reason(exit_reason::not_exited), m_host(nullptr) { m_node = get_middleman()->node(); }
void blocking_actor::await_all_other_actors_done() { get_actor_registry()->await_running_count_equal(1); }
scoped_actor::~scoped_actor() { if (!m_hidden) { get_actor_registry()->dec_running(); BOOST_ACTOR_SET_AID(m_prev); } }