int aeron_driver_receiver_init( aeron_driver_receiver_t *receiver, aeron_driver_context_t *context, aeron_system_counters_t *system_counters, aeron_distinct_error_log_t *error_log) { if (aeron_udp_transport_poller_init(&receiver->poller) < 0) { return -1; } for (size_t i = 0; i < AERON_DRIVER_RECEIVER_NUM_RECV_BUFFERS; i++) { size_t offset = 0; if (aeron_alloc_aligned( (void **)&receiver->recv_buffers.buffers[i], &offset, AERON_DRIVER_RECEIVER_MAX_UDP_PACKET_LENGTH, AERON_CACHE_LINE_LENGTH * 2) < 0) { int errcode = errno; aeron_set_err(errcode, "%s:%d: %s", __FILE__, __LINE__, strerror(errcode)); return -1; } receiver->recv_buffers.iov[i].iov_base = receiver->recv_buffers.buffers[i] + offset; receiver->recv_buffers.iov[i].iov_len = AERON_DRIVER_RECEIVER_MAX_UDP_PACKET_LENGTH; } receiver->images.array = NULL; receiver->images.length = 0; receiver->images.capacity = 0; receiver->pending_setups.array = NULL; receiver->pending_setups.length = 0; receiver->pending_setups.capacity = 0; receiver->context = context; receiver->error_log = error_log; receiver->receiver_proxy.command_queue = &context->receiver_command_queue; receiver->receiver_proxy.fail_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_RECEIVER_PROXY_FAILS); receiver->receiver_proxy.threading_mode = context->threading_mode; receiver->receiver_proxy.receiver = receiver; receiver->errors_counter = aeron_system_counter_addr(system_counters, AERON_SYSTEM_COUNTER_ERRORS); receiver->invalid_frames_counter = aeron_system_counter_addr(system_counters, AERON_SYSTEM_COUNTER_INVALID_PACKETS); receiver->total_bytes_received_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_BYTES_RECEIVED); return 0; }
int aeron_publication_image_create( aeron_publication_image_t **image, aeron_receive_channel_endpoint_t *endpoint, aeron_driver_context_t *context, int64_t correlation_id, int32_t session_id, int32_t stream_id, int32_t initial_term_id, int32_t active_term_id, int32_t initial_term_offset, aeron_position_t *rcv_hwm_position, aeron_position_t *rcv_pos_position, aeron_congestion_control_strategy_t *congestion_control, struct sockaddr_storage *control_address, struct sockaddr_storage *source_address, int32_t term_buffer_length, int32_t sender_mtu_length, aeron_loss_reporter_t *loss_reporter, bool is_reliable, bool is_sparse, aeron_system_counters_t *system_counters) { char path[AERON_MAX_PATH]; int path_length = aeron_publication_image_location( path, sizeof(path), context->aeron_dir, endpoint->conductor_fields.udp_channel->canonical_form, session_id, stream_id, correlation_id); aeron_publication_image_t *_image = NULL; const uint64_t usable_fs_space = context->usable_fs_space_func(context->aeron_dir); const uint64_t log_length = aeron_logbuffer_compute_log_length((uint64_t)term_buffer_length, context->file_page_size); bool is_multicast = endpoint->conductor_fields.udp_channel->multicast; int64_t now_ns = context->nano_clock(); *image = NULL; if (usable_fs_space < log_length) { aeron_set_err( ENOSPC, "Insufficient usable storage for new log of length=%" PRId64 " in %s", log_length, context->aeron_dir); return -1; } if (aeron_alloc((void **)&_image, sizeof(aeron_publication_image_t)) < 0) { aeron_set_err(ENOMEM, "%s", "Could not allocate publication image"); return -1; } _image->log_file_name = NULL; if (aeron_alloc((void **)(&_image->log_file_name), (size_t)path_length + 1) < 0) { aeron_free(_image); aeron_set_err(ENOMEM, "%s", "Could not allocate publication image log_file_name"); return -1; } if (aeron_loss_detector_init( &_image->loss_detector, is_multicast, is_multicast ? aeron_loss_detector_nak_multicast_delay_generator : aeron_loss_detector_nak_unicast_delay_generator, aeron_publication_image_on_gap_detected, _image) < 0) { aeron_free(_image); aeron_set_err(ENOMEM, "%s", "Could not init publication image loss detector"); return -1; } if (context->map_raw_log_func( &_image->mapped_raw_log, path, is_sparse, (uint64_t)term_buffer_length, context->file_page_size) < 0) { aeron_free(_image->log_file_name); aeron_free(_image); aeron_set_err(aeron_errcode(), "error mapping network raw log %s: %s", path, aeron_errmsg()); return -1; } _image->map_raw_log_close_func = context->map_raw_log_close_func; strncpy(_image->log_file_name, path, (size_t)path_length); _image->log_file_name[path_length] = '\0'; _image->log_file_name_length = (size_t)path_length; _image->log_meta_data = (aeron_logbuffer_metadata_t *)(_image->mapped_raw_log.log_meta_data.addr); _image->log_meta_data->initial_term_id = initial_term_id; _image->log_meta_data->mtu_length = sender_mtu_length; _image->log_meta_data->term_length = term_buffer_length; _image->log_meta_data->page_size = (int32_t)context->file_page_size; _image->log_meta_data->correlation_id = correlation_id; _image->log_meta_data->is_connected = 0; _image->log_meta_data->end_of_stream_position = INT64_MAX; aeron_logbuffer_fill_default_header( _image->mapped_raw_log.log_meta_data.addr, session_id, stream_id, initial_term_id); _image->endpoint = endpoint; _image->congestion_control = congestion_control; _image->loss_reporter = loss_reporter; _image->loss_reporter_offset = -1; _image->nano_clock = context->nano_clock; _image->epoch_clock = context->epoch_clock; _image->conductor_fields.subscribable.array = NULL; _image->conductor_fields.subscribable.length = 0; _image->conductor_fields.subscribable.capacity = 0; _image->conductor_fields.subscribable.add_position_hook_func = aeron_driver_subscribable_null_hook; _image->conductor_fields.subscribable.remove_position_hook_func = aeron_driver_subscribable_null_hook; _image->conductor_fields.subscribable.clientd = NULL; _image->conductor_fields.managed_resource.registration_id = correlation_id; _image->conductor_fields.managed_resource.clientd = _image; _image->conductor_fields.managed_resource.incref = NULL; _image->conductor_fields.managed_resource.decref = NULL; _image->conductor_fields.is_reliable = is_reliable; _image->conductor_fields.status = AERON_PUBLICATION_IMAGE_STATUS_ACTIVE; _image->conductor_fields.liveness_timeout_ns = context->image_liveness_timeout_ns; _image->session_id = session_id; _image->stream_id = stream_id; _image->rcv_hwm_position.counter_id = rcv_hwm_position->counter_id; _image->rcv_hwm_position.value_addr = rcv_hwm_position->value_addr; _image->rcv_pos_position.counter_id = rcv_pos_position->counter_id; _image->rcv_pos_position.value_addr = rcv_pos_position->value_addr; _image->initial_term_id = initial_term_id; _image->term_length_mask = (int32_t)term_buffer_length - 1; _image->position_bits_to_shift = (size_t)aeron_number_of_trailing_zeroes((int32_t)term_buffer_length); _image->mtu_length = sender_mtu_length; _image->last_sm_change_number = -1; _image->last_loss_change_number = -1; _image->is_end_of_stream = false; memcpy(&_image->control_address, control_address, sizeof(_image->control_address)); memcpy(&_image->source_address, source_address, sizeof(_image->source_address)); _image->heartbeats_received_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_HEARTBEATS_RECEIVED); _image->flow_control_under_runs_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_FLOW_CONTROL_UNDER_RUNS); _image->flow_control_over_runs_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_FLOW_CONTROL_OVER_RUNS); _image->status_messages_sent_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_STATUS_MESSAGES_SENT); _image->nak_messages_sent_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_NAK_MESSAGES_SENT); _image->loss_gap_fills_counter = aeron_system_counter_addr( system_counters, AERON_SYSTEM_COUNTER_LOSS_GAP_FILLS); const int64_t initial_position = aeron_logbuffer_compute_position( active_term_id, initial_term_offset, _image->position_bits_to_shift, initial_term_id); _image->begin_loss_change = -1; _image->end_loss_change = -1; _image->loss_term_id = active_term_id; _image->loss_term_offset = initial_term_offset; _image->loss_length = 0; _image->begin_sm_change = -1; _image->end_sm_change = -1; _image->next_sm_position = initial_position; _image->next_sm_receiver_window_length = _image->congestion_control->initial_window_length( _image->congestion_control->state); _image->last_sm_position = initial_position; _image->last_sm_position_window_limit = initial_position + _image->next_sm_receiver_window_length; _image->last_packet_timestamp_ns = now_ns; _image->last_status_message_timestamp = 0; _image->conductor_fields.clean_position = initial_position; _image->conductor_fields.time_of_last_status_change_ns = now_ns; aeron_counter_set_ordered(_image->rcv_hwm_position.value_addr, initial_position); aeron_counter_set_ordered(_image->rcv_pos_position.value_addr, initial_position); *image = _image; return 0; }