Example #1
0
void
actor_t::on_message(int fd,
                    const message_t& message)
{
    auto it = m_channels.find(fd);

    if(it == m_channels.end()) {
        return;
    }

    m_dispatch->invoke(message, std::make_shared<upstream_t>(
        it->second,
        message.band()
    ));
}
Example #2
0
void
session_t::invoke(const message_t& message) {
    channel_map_t::const_iterator lb, ub;
    channel_map_t::key_type index = message.band();

    std::shared_ptr<channel_t> channel;

    {
        auto locked = channels.synchronize();

        std::tie(lb, ub) = locked->equal_range(index);

        if(lb == ub) {
            if(!prototype || index <= max_channel) {
                return;
            }

            // NOTE: Checking whether channel number is always higher than the previous channel number
            // is similar to an infinite TIME_WAIT timeout for TCP sockets. It might be not the best
            // aproach, but since we have 2^64 possible channels, unlike 2^16 ports for sockets, it is
            // fit to avoid stray messages.

            max_channel = index;

            std::tie(lb, std::ignore) = locked->insert({index, std::make_shared<channel_t>(
                prototype,
                std::make_shared<basic_upstream_t>(shared_from_this(), index)
            )});
        }

        // NOTE: The virtual channel pointer is copied here so that if the slot decides to close the
        // virtual channel, it won't destroy it inside the channel_t::invoke(). Instead, it will be
        // destroyed when this function scope is exited, liberating us from thinking of some voodoo
        // magic to handle it.

        channel = lb->second;
    }

    channel->invoke(message);
}
Example #3
0
void
session_t::invoke(const message_t& message) {
    channel_map_t::const_iterator lb, ub;
    channel_map_t::key_type index = message.band();

    std::shared_ptr<channel_t> channel;

    {
        auto locked = channels.synchronize();

        std::tie(lb, ub) = locked->equal_range(index);

        if(lb == ub) {
            if(!prototype || index <= max_channel) {
                return;
            }

            max_channel = index;

            auto upstream = std::make_shared<upstream_t>(shared_from_this(), index);
            upstream->auto_revoke();

            std::tie(lb, std::ignore) = locked->insert({
                index,
                std::make_shared<channel_t>(prototype, upstream)
            });
        }

        // NOTE: The virtual channel pointer is copied here so that if the slot decides to close the
        // virtual channel, it won't destroy it inside the channel_t::invoke(). Instead, it will be
        // destroyed when this function scope is exited, liberating us from thinking of some voodoo
        // magic to handle it.

        channel = lb->second;
    }

    channel->invoke(message);
}