static void run_and_verify_should_retry(RETRY_CONTROL_HANDLE handle, time_t first_retry_time, time_t last_retry_time, time_t current_time, double secs_since_first_retry, double secs_since_last_retry, RETRY_ACTION expected_retry_action, bool is_first_check)
{
    // arrange
    umock_c_reset_all_calls();
    if (is_first_check)
    {
        STRICT_EXPECTED_CALL(get_time(NULL)).SetReturn(current_time);
    }
    else
    {
        STRICT_EXPECTED_CALL(get_time(NULL)).SetReturn(current_time);
        STRICT_EXPECTED_CALL(get_difftime(current_time, first_retry_time)).SetReturn(secs_since_first_retry);

        if (expected_retry_action != RETRY_ACTION_STOP_RETRYING)
        {
            STRICT_EXPECTED_CALL(get_difftime(current_time, last_retry_time)).SetReturn(secs_since_last_retry);
        }
    }

    if (expected_retry_action == RETRY_ACTION_RETRY_NOW)
    {
        STRICT_EXPECTED_CALL(get_time(NULL)).SetReturn(current_time);
    }

    // act
    RETRY_ACTION retry_action;
    int result = retry_control_should_retry(handle, &retry_action);

    // assert
    ASSERT_ARE_EQUAL(char_ptr, umock_c_get_expected_calls(), umock_c_get_actual_calls());
    ASSERT_ARE_EQUAL(int, 0, result);
    ASSERT_ARE_EQUAL(int, expected_retry_action, retry_action);
}
static int verify_cbs_put_token_timeout(AUTHENTICATION_INSTANCE* instance, bool* is_timed_out)
{
    int result;

    if (instance->current_sas_token_put_time == INDEFINITE_TIME)
    {
        result = __FAILURE__;
        LogError("Failed verifying if cbs_put_token has timed out (current_sas_token_put_time is not set)");
    }
    else
    {
        time_t current_time;

        if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
        {
            result = __FAILURE__;
            LogError("Failed verifying if cbs_put_token has timed out (get_time failed)");
        }
        // Codes_SRS_IOTHUBTRANSPORT_AMQP_AUTH_09_083: [authentication_do_work() shall check for authentication timeout comparing the current time since `instance->current_sas_token_put_time` to `instance->cbs_request_timeout_secs`]
        else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->cbs_request_timeout_secs)
        {
            *is_timed_out = true;
            result = RESULT_OK;
        }
        else
        {
            *is_timed_out = false;
            result = RESULT_OK;
        }
    }

    return result;
}
static int verify_sas_token_refresh_timeout(AUTHENTICATION_INSTANCE* instance, bool* is_timed_out)
{
    int result;

    if (instance->current_sas_token_put_time == INDEFINITE_TIME)
    {
        result = __FAILURE__;
        LogError("Failed verifying if SAS token refresh timed out (current_sas_token_put_time is not set)");
    }
    else
    {
        time_t current_time;

        if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
        {
            result = __FAILURE__;
            LogError("Failed verifying if SAS token refresh timed out (get_time failed)");
        }
        else if ((uint32_t)get_difftime(current_time, instance->current_sas_token_put_time) >= instance->sas_token_refresh_time_secs)
        {
            *is_timed_out = true;
            result = RESULT_OK;
        }
        else
        {
            *is_timed_out = false;
            result = RESULT_OK;
        }
    }

    return result;
}
COND_RESULT Condition_Wait(COND_HANDLE handle, LOCK_HANDLE lock, int timeout_milliseconds)
{
    COND_RESULT result;
    // Codes_SRS_CONDITION_18_004: [ Condition_Wait shall return COND_INVALID_ARG if handle is NULL ]
    // Codes_SRS_CONDITION_18_005: [ Condition_Wait shall return COND_INVALID_ARG if lock is NULL and timeout_milliseconds is 0 ]
    // Codes_SRS_CONDITION_18_006: [ Condition_Wait shall return COND_INVALID_ARG if lock is NULL and timeout_milliseconds is not 0 ]
    if (handle == NULL || lock == NULL)
    {
        result = COND_INVALID_ARG;
    }
    else
    {
        if (timeout_milliseconds > 0)
        {
            struct xtime tm;
            int wait_result;
            time_t now = get_time(NULL);

            // Codes_SRS_CONDITION_18_013: [ Condition_Wait shall accept relative timeouts ]
            tm.sec = (unsigned long)get_difftime(now, (time_t)0) + (timeout_milliseconds / 1000);
            tm.nsec = (timeout_milliseconds % 1000) * 1000000L;
            wait_result = cnd_timedwait((cnd_t *)handle, (mtx_t*)lock, &tm);
            if (wait_result == thrd_timedout)
            {
                // Codes_SRS_CONDITION_18_011: [ Condition_Wait shall return COND_TIMEOUT if the condition is NOT triggered and timeout_milliseconds is not 0 ]
                result = COND_TIMEOUT;
            }
            else if (wait_result == thrd_success)
            {
                // Codes_SRS_CONDITION_18_012: [ Condition_Wait shall return COND_OK if the condition is triggered and timeout_milliseconds is not 0 ]
                result = COND_OK;
            }
            else
            {
                LogError("Failed to Condition_Wait\r\n");
                result = COND_ERROR;
            }
        }
        else
        {
            if (cnd_wait((cnd_t*)handle, (mtx_t *)lock) != thrd_success)
            {
                LogError("Failed to cnd_wait\r\n");
                result = COND_ERROR;
            }
            else
            {
                // Codes_SRS_CONDITION_18_010: [ Condition_Wait shall return COND_OK if the condition is triggered and timeout_milliseconds is 0 ]
                result = COND_OK;
            }
        }
    }
    return result;
}
static int get_seconds_since_epoch(size_t* seconds)
{
    int result;
    time_t current_time;
    if ((current_time = get_time(NULL)) == INDEFINITE_TIME)
    {
        LogError("Failed getting the current local time (get_time() failed)");
        result = __FAILURE__;
    }
    else
    {
        *seconds = (size_t)get_difftime(current_time, (time_t)0);
        result = 0;
    }
    return result;
}
Пример #6
0
void* worker_arq_watcher(void *arg)
{
    worker_t  *w = (worker_t*)arg;
    monitor_t *m = w->m;
    struct timeval current_time;
    int difftime_ms;
    int idx;

    int i, oldest;
    int flag = 0;

    mpudp_packet_t *p;

    while(1)
    {
        /* printf("[%d] - ARQ watcher alive\n", w->id); */

        flag = 0;

        if(w->state == WORKER_NOT_CONNECTED)
        {
            /* printf("[%d] - still not connected\n", w->id); */
            sleep(1);
            continue;
        }

        pthread_mutex_lock(&w->wait_ack_buff_mx);

        gettimeofday(&current_time, NULL);

        for(i = 0; i < BUFF_LEN; i++)
        {
            idx = (w->ack_tail + i) % BUFF_LEN;
            /* idx = w->ack_tail; */

            p = w->wait_ack_buff[idx];
            difftime_ms = get_difftime(&current_time, &w->last_send_time[idx]);

            if(p != NULL && (difftime_ms > 5000))
            {
                printf("[%d] - should retransmit %d\n", w->id, p->id);
                flag = 1;

                if(w->arq_count[idx] > 6)
                {
                    printf("[%d] - link is dead!\n", w->id);
                    /* shutdown_worker(w); */
                    pthread_mutex_unlock(&w->wait_ack_buff_mx);
                    reconfigure_workers(m);
                    continue;
                }

                w->arq_count[idx]++;

                pthread_mutex_lock(&w->private_tx_buff_mx);
                while(w->private_tx_buff != NULL)
                {
                    pthread_cond_wait(&w->tx_empty, &w->private_tx_buff_mx);
                }

                gettimeofday(&w->last_send_time[idx], NULL);
                w->private_tx_buff = w->wait_ack_buff[idx];

                pthread_cond_broadcast(&w->tx_ready);
                pthread_mutex_unlock(&w->private_tx_buff_mx);
                break;
            }
        }

        pthread_mutex_unlock(&w->wait_ack_buff_mx);

        if(flag == 0)
            usleep(500000);
        else
            usleep(10000);
    }
}