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); }
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; }
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; }