コード例 #1
0
void aeron_driver_receiver_on_add_endpoint(void *clientd, void *command)
{
    aeron_driver_receiver_t *receiver = (aeron_driver_receiver_t *)clientd;
    aeron_command_base_t *cmd = (aeron_command_base_t *)command;
    aeron_receive_channel_endpoint_t *endpoint = (aeron_receive_channel_endpoint_t *)cmd->item;
    aeron_udp_channel_t *udp_channel = endpoint->conductor_fields.udp_channel;

    if (aeron_udp_transport_poller_add(&receiver->poller, &endpoint->transport) < 0)
    {
        AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver on_add_endpoint: %s", aeron_errmsg());
    }

    if (udp_channel->explicit_control)
    {
        if (aeron_driver_receiver_add_pending_setup(receiver, endpoint, 0, 0, &udp_channel->local_control) < 0)
        {
            AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver on_add_endpoint: %s", aeron_errmsg());
        }

        if (aeron_receive_channel_endpoint_send_sm(
            endpoint,
            &udp_channel->local_control,
            0,
            0,
            0,
            0,
            0,
            AERON_STATUS_MESSAGE_HEADER_SEND_SETUP_FLAG) < 0)
        {
            AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver on_add_endpoint send SM: %s", aeron_errmsg());
        }
    }

    aeron_driver_conductor_proxy_on_delete_cmd(receiver->context->conductor_proxy, command);
}
コード例 #2
0
int aeron_publication_image_send_pending_status_message(aeron_publication_image_t *image)
{
    int work_count = 0;

    if (NULL != image->endpoint && AERON_PUBLICATION_IMAGE_STATUS_ACTIVE == image->conductor_fields.status)
    {
        int64_t change_number;
        AERON_GET_VOLATILE(change_number, image->end_sm_change);

        if (change_number != image->last_sm_change_number)
        {
            const int64_t sm_position = image->next_sm_position;
            const int32_t receiver_window_length = image->next_sm_receiver_window_length;

            aeron_acquire();

            if (change_number == image->begin_sm_change)
            {
                const int32_t term_id = aeron_logbuffer_compute_term_id_from_position(
                    sm_position, image->position_bits_to_shift, image->initial_term_id);
                const int32_t term_offset = (int32_t)(sm_position & image->term_length_mask);

                int send_sm_result = aeron_receive_channel_endpoint_send_sm(
                    image->endpoint,
                    &image->control_address,
                    image->stream_id,
                    image->session_id,
                    term_id,
                    term_offset,
                    receiver_window_length,
                    0);

                aeron_counter_ordered_increment(image->status_messages_sent_counter, 1);

                image->last_sm_change_number = change_number;
                image->last_sm_position = sm_position;
                image->last_sm_position_window_limit = sm_position + receiver_window_length;
                work_count = send_sm_result < 0 ? send_sm_result : 1;
            }
        }
    }

    return work_count;
}
コード例 #3
0
int aeron_driver_receiver_do_work(void *clientd)
{
    struct mmsghdr mmsghdr[AERON_DRIVER_RECEIVER_NUM_RECV_BUFFERS];
    aeron_driver_receiver_t *receiver = (aeron_driver_receiver_t *)clientd;
    int64_t bytes_received = 0;
    int work_count = 0;

    work_count += aeron_spsc_concurrent_array_queue_drain(
        receiver->receiver_proxy.command_queue, aeron_driver_receiver_on_command, receiver, 10);

    for (size_t i = 0; i < AERON_DRIVER_RECEIVER_NUM_RECV_BUFFERS; i++)
    {
        mmsghdr[i].msg_hdr.msg_name = &receiver->recv_buffers.addrs[i];
        mmsghdr[i].msg_hdr.msg_namelen = sizeof(receiver->recv_buffers.addrs[i]);
        mmsghdr[i].msg_hdr.msg_iov = &receiver->recv_buffers.iov[i];
        mmsghdr[i].msg_hdr.msg_iovlen = 1;
        mmsghdr[i].msg_hdr.msg_flags = 0;
        mmsghdr[i].msg_hdr.msg_control = NULL;
        mmsghdr[i].msg_hdr.msg_controllen = 0;
        mmsghdr[i].msg_len = 0;
    }

    int poll_result = aeron_udp_transport_poller_poll(
        &receiver->poller,
        mmsghdr,
        AERON_DRIVER_RECEIVER_NUM_RECV_BUFFERS,
        aeron_receive_channel_endpoint_dispatch,
        receiver);

    if (poll_result < 0)
    {
        AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver poller_poll: %s", aeron_errmsg());
    }

    for (int i = 0; i < poll_result; i++)
    {
        bytes_received += mmsghdr[i].msg_len;
        work_count++;
    }

    aeron_counter_add_ordered(receiver->total_bytes_received_counter, bytes_received);

    int64_t now_ns = receiver->context->nano_clock();

    for (size_t i = 0, length = receiver->images.length; i < length; i++)
    {
        aeron_publication_image_t *image = receiver->images.array[i].image;

        int send_sm_result = aeron_publication_image_send_pending_status_message(image);
        if (send_sm_result < 0)
        {
            AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver send SM: %s", aeron_errmsg());
        }

        work_count += (send_sm_result < 0) ? 0 : send_sm_result;

        int send_nak_result = aeron_publication_image_send_pending_loss(image);
        if (send_nak_result < 0)
        {
            AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver send NAK: %s", aeron_errmsg());
        }

        work_count += (send_nak_result < 0) ? 0 : send_nak_result;

        int initiate_rttm_result = aeron_publication_image_initiate_rttm(image, now_ns);
        if (send_nak_result < 0)
        {
            AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver send RTTM: %s", aeron_errmsg());
        }

        work_count += (initiate_rttm_result < 0) ? 0 : initiate_rttm_result;
    }

    for (int last_index = (int)receiver->pending_setups.length - 1, i = last_index; i >= 0; i--)
    {
        aeron_driver_receiver_pending_setup_entry_t *entry = &receiver->pending_setups.array[i];

        if (now_ns > (entry->time_of_status_message_ns + AERON_DRIVER_RECEIVER_PENDING_SETUP_TIMEOUT_NS))
        {
            if (!entry->is_periodic)
            {
                if (aeron_receive_channel_endpoint_on_remove_pending_setup(
                    entry->endpoint, entry->session_id, entry->stream_id) < 0)
                {
                    AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver pending setups: %s", aeron_errmsg());
                }

                aeron_array_fast_unordered_remove(
                    (uint8_t *) receiver->pending_setups.array,
                    sizeof(aeron_driver_receiver_pending_setup_entry_t),
                    (size_t)i,
                    (size_t)last_index);
                last_index--;
                receiver->pending_setups.length--;
            }
            else if (aeron_receive_channel_endpoint_should_elicit_setup_message(entry->endpoint))
            {
                if (aeron_receive_channel_endpoint_send_sm(
                    entry->endpoint,
                    &entry->control_addr,
                    entry->stream_id,
                    entry->session_id,
                    0,
                    0,
                    0,
                    AERON_STATUS_MESSAGE_HEADER_SEND_SETUP_FLAG) < 0)
                {
                    AERON_DRIVER_RECEIVER_ERROR(receiver, "receiver send periodic SM: %s", aeron_errmsg());
                }
                entry->time_of_status_message_ns = now_ns;
            }
        }
    }

    return work_count;
}