Esempio n. 1
0
static HG_THREAD_RETURN_TYPE
thread_cb_cond_all(void *arg)
{
    hg_thread_ret_t thread_ret = (hg_thread_ret_t) 0;
    (void) arg;

    hg_thread_mutex_lock(&thread_mutex);

    while (working)
        hg_thread_cond_timedwait(&thread_cond, &thread_mutex, 1000);

    hg_thread_mutex_unlock(&thread_mutex);

    hg_thread_exit(thread_ret);
    return thread_ret;
}
Esempio n. 2
0
/*---------------------------------------------------------------------------*/
na_return_t
NA_Trigger(na_context_t *context, unsigned int timeout, unsigned int max_count,
        unsigned int *actual_count)
{
    struct na_private_context *na_private_context =
            (struct na_private_context *) context;
    na_return_t ret = NA_SUCCESS;
    na_bool_t completion_queue_empty = 0;
    struct na_cb_completion_data *completion_data = NULL;
    unsigned int count = 0;

    if (!context) {
        NA_LOG_ERROR("NULL context");
        ret = NA_INVALID_PARAM;
        goto done;
    }

    while (count < max_count) {
        hg_thread_mutex_lock(&na_private_context->completion_queue_mutex);

        /* Is completion queue empty */
        completion_queue_empty = (na_bool_t) hg_queue_is_empty(
                na_private_context->completion_queue);

        while (completion_queue_empty) {
            /* TODO needed ? */
            /* If queue is empty and already triggered something, just leave */
            if (count) {
                hg_thread_mutex_unlock(
                        &na_private_context->completion_queue_mutex);
                goto done;
            }

            if (!timeout) {
                /* Timeout is 0 so leave */
                ret = NA_TIMEOUT;
                hg_thread_mutex_unlock(
                        &na_private_context->completion_queue_mutex);
                goto done;
            }
            /* Otherwise wait timeout ms */
            if (hg_thread_cond_timedwait(
                    &na_private_context->completion_queue_cond,
                    &na_private_context->completion_queue_mutex, timeout)
                    != HG_UTIL_SUCCESS) {
                /* Timeout occurred so leave */
                ret = NA_TIMEOUT;
                hg_thread_mutex_unlock(
                        &na_private_context->completion_queue_mutex);
                goto done;
            }
        }

        /* Completion queue should not be empty now */
        completion_data = (struct na_cb_completion_data *)
                    hg_queue_pop_tail(na_private_context->completion_queue);
        if (!completion_data) {
            NA_LOG_ERROR("NULL completion data");
            ret = NA_INVALID_PARAM;
            hg_thread_mutex_unlock(&na_private_context->completion_queue_mutex);
            goto done;
        }

        /* Unlock now so that other threads can eventually add callbacks
         * to the queue while callback gets executed */
        hg_thread_mutex_unlock(&na_private_context->completion_queue_mutex);

        /* Execute callback */
        if (completion_data->callback) {
            /* TODO should return error from callback ? */
            completion_data->callback(completion_data->callback_info);
        }

        /* Execute plugin callback (free resources etc) */
        if (completion_data->plugin_callback)
            completion_data->plugin_callback(completion_data->callback_info,
                    completion_data->plugin_callback_args);

        free(completion_data);
        count++;
    }

    if (actual_count) *actual_count = count;

done:
    return ret;
}
Esempio n. 3
0
/*---------------------------------------------------------------------------*/
na_return_t
NA_Progress(na_class_t *na_class, na_context_t *context, unsigned int timeout)
{
    struct na_private_context *na_private_context =
            (struct na_private_context *) context;
    double remaining = timeout / 1000.0; /* Convert timeout in ms into seconds */
    na_return_t ret = NA_SUCCESS;

    if (!na_class) {
        NA_LOG_ERROR("NULL NA class");
        ret = NA_INVALID_PARAM;
        goto done;
    }
    if (!context) {
        NA_LOG_ERROR("NULL context");
        ret = NA_INVALID_PARAM;
        goto done;
    }
    if (!na_class->progress) {
        NA_LOG_ERROR("progress plugin callback is not defined");
        ret = NA_PROTOCOL_ERROR;
        goto done;
    }

    /* TODO option for concurrent progress */

    /* Prevent multiple threads from concurrently calling progress on the same
     * context */
    hg_thread_mutex_lock(&na_private_context->progress_mutex);

    while (na_private_context->progressing) {
        hg_time_t t1, t2;

        if (remaining <= 0) {
            /* Timeout is 0 so leave */
            hg_thread_mutex_unlock(&na_private_context->progress_mutex);
            ret = NA_TIMEOUT;
            goto done;
        }

        hg_time_get_current(&t1);

        if (hg_thread_cond_timedwait(&na_private_context->progress_cond,
                &na_private_context->progress_mutex,
                (unsigned int) (remaining * 1000)) != HG_UTIL_SUCCESS) {
            /* Timeout occurred so leave */
            hg_thread_mutex_unlock(&na_private_context->progress_mutex);
            ret = NA_TIMEOUT;
            goto done;
        }

        hg_time_get_current(&t2);
        remaining -= hg_time_to_double(hg_time_subtract(t2, t1));
        if (remaining < 0) {
            /* Give a chance to call progress with timeout of 0 if
             * progressing is NA_FALSE */
            remaining = 0;
        }
    }
    na_private_context->progressing = NA_TRUE;

    hg_thread_mutex_unlock(&na_private_context->progress_mutex);

    /* Try to make progress for remaining time */
    ret = na_class->progress(na_class, context,
            (unsigned int) (remaining * 1000));

    hg_thread_mutex_lock(&na_private_context->progress_mutex);

    /* At this point, either progress succeeded or failed with NA_TIMEOUT,
     * meaning remaining time is now 0, so wake up other threads waiting */
    na_private_context->progressing = NA_FALSE;
    hg_thread_cond_signal(&na_private_context->progress_cond);

    hg_thread_mutex_unlock(&na_private_context->progress_mutex);

done:
    return ret;
}