Exemplo n.º 1
0
int aeron_static_window_congestion_control_strategy_supplier(
    aeron_congestion_control_strategy_t **strategy,
    const char *channel,
    int32_t stream_id,
    int32_t session_id,
    int64_t registration_id,
    int32_t term_length,
    int32_t sender_mtu_length,
    aeron_driver_context_t *context,
    aeron_counters_manager_t *counters_manager)
{
    aeron_congestion_control_strategy_t *_strategy;

    if (aeron_alloc((void **)&_strategy, sizeof(aeron_congestion_control_strategy_t)) < 0 ||
        aeron_alloc((void **)&_strategy->state, sizeof(aeron_static_window_congestion_control_strategy_state_t)) < 0)
    {
        return -1;
    }

    _strategy->should_measure_rtt = aeron_static_window_congestion_control_strategy_should_measure_rtt;
    _strategy->on_rttm = aeron_static_window_congestion_control_strategy_on_rttm;
    _strategy->on_track_rebuild = aeron_static_window_congestion_control_strategy_on_track_rebuild;
    _strategy->initial_window_length = aeron_static_window_congestion_control_strategy_initial_window_length;
    _strategy->fini = aeron_static_window_congestion_control_strategy_fini;

    aeron_static_window_congestion_control_strategy_state_t *state = _strategy->state;
    const int32_t initial_window_length = (int32_t)context->initial_window_length;
    const int32_t max_window_for_term = term_length / 2;

    state->window_length = max_window_for_term < initial_window_length ? max_window_for_term : initial_window_length;

    *strategy = _strategy;
    return 0;
}
Exemplo n.º 2
0
int aeron_max_multicast_flow_control_strategy_supplier(
    aeron_flow_control_strategy_t **strategy,
    size_t channel_length,
    const char *channel,
    int32_t stream_id,
    int64_t registration_id,
    int32_t initial_term_id,
    size_t term_length)
{
    aeron_flow_control_strategy_t *_strategy;

    if (aeron_alloc((void **)&_strategy, sizeof(aeron_flow_control_strategy_t)) < 0 ||
        aeron_alloc((void **)&_strategy->state, sizeof(aeron_max_flow_control_strategy_state_t)) < 0)
    {
        return -1;
    }

    _strategy->on_idle = aeron_max_flow_control_strategy_on_idle;
    _strategy->on_status_message = aeron_max_flow_control_strategy_on_sm;
    _strategy->should_linger = aeron_max_flow_control_strategy_should_linger;
    _strategy->fini = aeron_max_flow_control_strategy_fini;

    aeron_max_flow_control_strategy_state_t *state = (aeron_max_flow_control_strategy_state_t *)_strategy->state;
    state->last_position = 0;
    state->time_of_last_status_message = 0;
    state->should_linger = true;

    *strategy = _strategy;

    return 0;
}
Exemplo n.º 3
0
int aeron_distinct_error_log_init(
    aeron_distinct_error_log_t *log,
    uint8_t *buffer,
    size_t buffer_size,
    aeron_clock_func_t clock,
    aeron_resource_linger_func_t linger,
    void *clientd)
{
    if (NULL == log || NULL == clock || NULL == linger)
    {
        aeron_set_err(EINVAL, "%s", "invalid argument");
        return -1;
    }

    if (aeron_alloc((void **)&log->observations_pimpl, sizeof(aeron_distinct_error_log_observations_pimpl_t)) < 0)
    {
        return -1;
    }

    log->buffer = buffer;
    log->buffer_capacity = buffer_size;
    log->clock = clock;
    log->linger_resource = linger;
    log->linger_resource_clientd = clientd;
    log->next_offset = 0;
    atomic_store(&log->observations_pimpl->num_observations, 0);
    atomic_store(&log->observations_pimpl->observations, NULL);
    pthread_mutex_init(&log->mutex, NULL);

    return 0;
}
Exemplo n.º 4
0
int aeron_counters_manager_init(
    volatile aeron_counters_manager_t *manager,
    uint8_t *metadata_buffer,
    size_t metadata_length,
    uint8_t *values_buffer,
    size_t values_length,
    aeron_counters_manager_clock_func_t clock_func,
    int64_t free_to_reuse_timeout_ms)
{
    int result = -1;

    if (AERON_COUNTERS_MANAGER_IS_VALID_BUFFER_SIZES(metadata_length, values_length))
    {
        manager->metadata = metadata_buffer;
        manager->metadata_length = metadata_length;
        manager->values = values_buffer;
        manager->values_length = values_length;
        manager->id_high_water_mark = -1;
        manager->free_list_index = -1;
        manager->free_list_length = 2;
        manager->clock_func = clock_func;
        manager->free_to_reuse_timeout_ms = free_to_reuse_timeout_ms;
        result = aeron_alloc((void **)&manager->free_list, sizeof(int32_t) * manager->free_list_length);
    }
    else
    {
        aeron_set_err(EINVAL, "%s:%d: %s", __FILE__, __LINE__, strerror(EINVAL));
    }

    return result;
}
Exemplo n.º 5
0
int aeron_alloc_aligned(void **ptr, size_t *offset, size_t size, size_t alignment)
{
    if (!(AERON_IS_POWER_OF_TWO(alignment)))
    {
        errno = EINVAL;
        return -1;
    }

    int result = aeron_alloc(ptr, size + alignment);
    if (result < 0)
    {
        return -1;
    }

    intptr_t addr = (intptr_t)*ptr;
    *offset = alignment - (addr & (alignment - 1));

    return 0;
}
int aeron_spsc_concurrent_array_queue_init(
    volatile aeron_spsc_concurrent_array_queue_t *queue, uint64_t length)
{
    length = (uint64_t)aeron_find_next_power_of_two((int32_t)length);

    if (aeron_alloc((void **)&queue->buffer, sizeof(void *) * length) < 0)
    {
        return -1;
    }

    for (size_t i = 0; i < length; i++)
    {
        queue->buffer[i] = NULL;
    }

    queue->producer.head_cache = 0;
    queue->producer.tail = 0;
    queue->consumer.head = 0;
    queue->capacity = length;
    queue->mask = length - 1;
    return 0;
}
Exemplo n.º 7
0
static aeron_distinct_observation_t *aeron_distinct_error_log_new_observation(
    aeron_distinct_error_log_t *log,
    size_t existing_num_observations,
    int64_t timestamp,
    int error_code,
    const char *description,
    const char *message)
{
    size_t num_observations = atomic_load(&log->observations_pimpl->num_observations);
    aeron_distinct_observation_t *observations = atomic_load(&log->observations_pimpl->observations);
    aeron_distinct_observation_t *observation = NULL;

    if ((observation = aeron_distinct_error_log_find_observation(
        observations, existing_num_observations, error_code, description)) == NULL)
    {
        char encoded_error[AERON_MAX_PATH];

        snprintf(encoded_error, sizeof(encoded_error) - 1, "%d: %s %s", error_code, description, message);

        size_t description_length = strlen(description);
        size_t encoded_error_length = strlen(encoded_error);
        size_t length = AERON_ERROR_LOG_HEADER_LENGTH + encoded_error_length;
        aeron_distinct_observation_t *new_array = NULL;
        char *new_description = NULL;
        size_t offset = log->next_offset;
        aeron_error_log_entry_t *entry = (aeron_error_log_entry_t *)(log->buffer + offset);

        if ((offset + length) > log->buffer_capacity ||
            aeron_alloc((void **)&new_array, sizeof(aeron_distinct_observation_t) * (num_observations + 1)) < 0 ||
            aeron_alloc((void **)&new_description, description_length + 1) < 0)
        {
            return NULL;
        }

        memcpy(log->buffer + offset + AERON_ERROR_LOG_HEADER_LENGTH, encoded_error, encoded_error_length);
        entry->first_observation_timestamp = timestamp;
        entry->observation_count = 0;

        log->next_offset = AERON_ALIGN(offset + length, AERON_ERROR_LOG_RECORD_ALIGNMENT);

        new_array[0].error_code = error_code;
        new_array[0].description = new_description;
        strncpy(new_description, description, description_length + 1);
        new_array[0].description_length = description_length;
        new_array[0].offset = offset;
        memcpy(&new_array[1], observations, sizeof(aeron_distinct_observation_t) * num_observations);

        atomic_store(&log->observations_pimpl->observations, new_array);
        atomic_store(&log->observations_pimpl->num_observations, num_observations + 1);

        AERON_PUT_ORDERED(entry->length, length);

        observation = &new_array[0];

        if (NULL != log->linger_resource)
        {
            log->linger_resource(log->linger_resource_clientd, (uint8_t *)observations);
        }
    }

    return observation;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
int aeron_udp_channel_parse(const char *uri, size_t uri_length, aeron_udp_channel_t **channel)
{
    aeron_udp_channel_t *_channel = NULL;
    struct sockaddr_storage endpoint_addr, explicit_control_addr, interface_addr;
    unsigned int interface_index = 0;

    memset(&endpoint_addr, 0, sizeof(endpoint_addr));
    memset(&explicit_control_addr, 0, sizeof(explicit_control_addr));
    memset(&interface_addr, 0, sizeof(interface_addr));

    if (aeron_alloc((void **)&_channel, sizeof(aeron_udp_channel_t)) < 0)
    {
        aeron_set_err(ENOMEM, "%s", "could not allocate UDP channel");
        return -1;
    }

    if (aeron_uri_parse(uri, &_channel->uri) < 0)
    {
        goto error_cleanup;
    }

    size_t copy_length = sizeof(_channel->original_uri) - 1;
    copy_length = uri_length < copy_length ? uri_length : copy_length;

    strncpy(_channel->original_uri, uri, copy_length);
    _channel->original_uri[copy_length] = '\0';
    _channel->uri_length = copy_length;

    _channel->explicit_control = false;
    _channel->multicast = false;

    if (_channel->uri.type != AERON_URI_UDP)
    {
        aeron_set_err(EINVAL, "%s", "UDP channels must use UDP URIs");
        goto error_cleanup;
    }

    if (NULL == _channel->uri.params.udp.endpoint_key && NULL == _channel->uri.params.udp.control_key)
    {
        aeron_set_err(EINVAL, "%s", "Aeron URIs for UDP must specify an endpoint address and/or a control address");
        goto error_cleanup;
    }

    if (NULL != _channel->uri.params.udp.endpoint_key)
    {
        if (aeron_host_and_port_parse_and_resolve(_channel->uri.params.udp.endpoint_key, &endpoint_addr) < 0)
        {
            aeron_set_err(
                aeron_errcode(),
                "could not resolve endpoint address=(%s): %s",
                _channel->uri.params.udp.endpoint_key, aeron_errmsg());
            goto error_cleanup;
        }
    }
    else
    {
        aeron_set_ipv4_wildcard_host_and_port(&endpoint_addr);
    }

    if (NULL != _channel->uri.params.udp.control_key)
    {
        if (aeron_host_and_port_parse_and_resolve(_channel->uri.params.udp.control_key, &explicit_control_addr) < 0)
        {
            aeron_set_err(
                aeron_errcode(),
                "could not resolve control address=(%s): %s",
                _channel->uri.params.udp.control_key, aeron_errmsg());
            goto error_cleanup;
        }
    }

    if (aeron_is_addr_multicast(&endpoint_addr))
    {
        memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr));
        if (aeron_multicast_control_address(&endpoint_addr, &_channel->remote_control) < 0)
        {
            goto error_cleanup;
        }

        if (aeron_find_multicast_interface(
            endpoint_addr.ss_family, _channel->uri.params.udp.interface_key, &interface_addr, &interface_index) < 0)
        {
            aeron_set_err(
                aeron_errcode(),
                "could not find interface=(%s): %s",
                _channel->uri.params.udp.interface_key, aeron_errmsg());
            goto error_cleanup;
        }

        _channel->interface_index = interface_index;
        _channel->multicast_ttl = aeron_uri_multicast_ttl(&_channel->uri);
        memcpy(&_channel->local_data, &interface_addr, AERON_ADDR_LEN(&interface_addr));
        memcpy(&_channel->local_control, &interface_addr, AERON_ADDR_LEN(&interface_addr));
        aeron_uri_udp_canonicalise(
            _channel->canonical_form, sizeof(_channel->canonical_form), &interface_addr, &endpoint_addr);
        _channel->canonical_length = strlen(_channel->canonical_form);
        _channel->multicast = true;
    }
    else if (NULL != _channel->uri.params.udp.control_key)
    {
        _channel->interface_index = 0;
        _channel->multicast_ttl = 0;
        memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr));
        memcpy(&_channel->remote_control, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr));
        memcpy(&_channel->local_data, &explicit_control_addr, AERON_ADDR_LEN(&explicit_control_addr));
        memcpy(&_channel->local_control, &explicit_control_addr, AERON_ADDR_LEN(&explicit_control_addr));
        aeron_uri_udp_canonicalise(
            _channel->canonical_form, sizeof(_channel->canonical_form), &explicit_control_addr, &endpoint_addr);
        _channel->canonical_length = strlen(_channel->canonical_form);
        _channel->explicit_control = true;
    }
    else
    {
        if (aeron_find_unicast_interface(
            endpoint_addr.ss_family, _channel->uri.params.udp.interface_key, &interface_addr, &interface_index) < 0)
        {
            goto error_cleanup;
        }

        _channel->interface_index = interface_index;
        _channel->multicast_ttl = 0;
        memcpy(&_channel->remote_data, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr));
        memcpy(&_channel->remote_control, &endpoint_addr, AERON_ADDR_LEN(&endpoint_addr));
        memcpy(&_channel->local_data, &interface_addr, AERON_ADDR_LEN(&interface_addr));
        memcpy(&_channel->local_control, &interface_addr, AERON_ADDR_LEN(&interface_addr));
        aeron_uri_udp_canonicalise(
            _channel->canonical_form, sizeof(_channel->canonical_form), &interface_addr, &endpoint_addr);
        _channel->canonical_length = strlen(_channel->canonical_form);
    }

    *channel = _channel;
    return 0;

    error_cleanup:
        *channel = NULL;
        if (NULL != _channel)
        {
            aeron_udp_channel_delete(_channel);
        }

        return -1;
}