コード例 #1
0
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);
}
コード例 #2
0
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();
    }
}
コード例 #3
0
ファイル: scoped_actor.cpp プロジェクト: syoummer/boost.actor
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());
    }
}
コード例 #4
0
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)));
}
コード例 #5
0
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);
    }
}
コード例 #6
0
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();
}
コード例 #7
0
 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;
     }
 }
コード例 #8
0
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());
    }
}
コード例 #9
0
ファイル: actor.cpp プロジェクト: Zhouxiaoqing/libcppa
actor::actor()
: m_id(get_actor_registry()->next_id()), m_is_proxy(false)
, m_exit_reason(exit_reason::not_exited) { }
コード例 #10
0
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);
}
コード例 #11
0
ファイル: abstract_actor.cpp プロジェクト: zoujiaqing/libcppa
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();
}
コード例 #12
0
ファイル: blocking_actor.cpp プロジェクト: zoujiaqing/libcppa
void blocking_actor::await_all_other_actors_done() {
    get_actor_registry()->await_running_count_equal(1);
}
コード例 #13
0
ファイル: scoped_actor.cpp プロジェクト: syoummer/boost.actor
scoped_actor::~scoped_actor() {
    if (!m_hidden) {
        get_actor_registry()->dec_running();
        BOOST_ACTOR_SET_AID(m_prev);
    }
}