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();
    }
}
Beispiel #2
0
void local_actor::forward_message(const actor_ptr& new_receiver) {
    if (new_receiver == nullptr) {
        return;
    }
    auto& from = last_sender();
    auto id = m_current_node->mid;
    if (id.valid() == false || id.is_response()) {
        new_receiver->enqueue(from.get(), m_current_node->msg);
    }
    else {
        new_receiver->sync_enqueue(from.get(), id, m_current_node->msg);
        // treat this message as asynchronous message from now on
        m_current_node->mid = message_id_t();
    }
}
Beispiel #3
0
void actor_registry::put(actor_id key, const actor_ptr& value) {
    bool add_attachable = false;
    if (value != nullptr) {
        shared_guard guard(m_instances_mtx);
        auto i = m_entries.find(key);
        if (i == m_entries.end()) {
            auto entry = std::make_pair(key,
                                        value_type(value,
                                                   exit_reason::not_exited));
            upgrade_guard uguard(guard);
            add_attachable = m_entries.insert(entry).second;
        }
    }
    if (add_attachable) {
        CPPA_LOG_INFO("added " << key);
        struct eraser : attachable {
            actor_id m_id;
            actor_registry* m_registry;
            eraser(actor_id id, actor_registry* s) : m_id(id), m_registry(s) { }
            void actor_exited(std::uint32_t reason) {
                m_registry->erase(m_id, reason);
            }
            bool matches(const token&) {
                return false;
            }
        };
        value->attach(new eraser(key, this));
    }
}
Beispiel #4
0
void local_actor::forward_message(const actor_ptr& dest, message_priority p) {
    if (dest == nullptr) return;
    auto& id = m_current_node->mid;
    dest->enqueue({last_sender(), dest, id, p}, m_current_node->msg);
    // treat this message as asynchronous message from now on
    id = message_id{};
}
 inline void operator()(const actor_ptr& sender, const message_id& mid) const {
     CPPA_REQUIRE(rsn != exit_reason::not_exited);
     if (mid.is_request() && sender != nullptr) {
         sender->enqueue({nullptr, sender, mid.response_id()},
                         make_any_tuple(atom("EXITED"), rsn));
     }
 }
Beispiel #6
0
bool actor::unlink_from_impl(const actor_ptr& other) {
    guard_type guard{m_mtx};
    // remove_backlink returns true if this actor is linked to other
    if (other && !exited() && other->remove_backlink(this)) {
        auto i = std::find(m_links.begin(), m_links.end(), other);
        CPPA_REQUIRE(i != m_links.end());
        m_links.erase(i);
        return true;
    }
    return false;
}
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());
    }
}
Beispiel #8
0
bool actor::link_to_impl(const actor_ptr& other) {
    if (other && other != this) {
        guard_type guard{m_mtx};
        // send exit message if already exited
        if (exited()) {
            send_as(this, other, atom("EXIT"), exit_reason());
        }
        // add link if not already linked to other
        // (checked by establish_backlink)
        else if (other->establish_backlink(this)) {
            m_links.push_back(other);
            return true;
        }
    }
    return false;
}
Beispiel #9
0
/**
 * @brief Sends @p what as a synchronous message to @p whom.
 * @param whom Receiver of the message.
 * @param what Message content as tuple.
 * @returns A handle identifying a future to the response of @p whom.
 * @warning The returned handle is actor specific and the response to the sent
 *          message cannot be received by another actor.
 * @throws std::invalid_argument if <tt>whom == nullptr</tt>
 */
inline message_future sync_send_tuple(const actor_ptr& whom, any_tuple what) {
    if (whom) return self->send_sync_message(whom.get(), std::move(what));
    else throw std::invalid_argument("whom == nullptr");
}
Beispiel #10
0
inline typename std::enable_if<std::is_base_of<channel, C>::value>::type
send_tuple_as(const actor_ptr& from, const intrusive_ptr<C>& whom, any_tuple what) {
    if (whom) whom->enqueue(from.get(), std::move(what));
}
Beispiel #11
0
void local_actor::demonitor(const actor_ptr& whom) {
    attachable::token mtoken{typeid(down_observer), this};
    if (whom) whom->detach(mtoken);
}
Beispiel #12
0
void local_actor::monitor(const actor_ptr& whom) {
    if (whom) whom->attach(attachable_ptr{new down_observer(this, whom)});
}
Beispiel #13
0
void local_actor::monitor(actor_ptr whom) {
    if (whom) whom->attach(new down_observer(this, whom));
}