Пример #1
0
int gop_waitall(op_generic_t *g)
{
    int status;
    op_generic_t *g2;
    callback_t *cb;

//log_printf(15, "START gid=%d type=%d\n", gop_id(g), gop_get_type(g));
    log_printf(5, "START gid=%d type=%d\n", gop_id(g), gop_get_type(g));
    lock_gop(g);

    if (gop_get_type(g) == Q_TYPE_QUE) {
        log_printf(15, "sync_exec_que_check gid=%d stack_size=%d started_exec=%d\n", gop_id(g), stack_size(g->q->opque->qd.list), g->base.started_execution);

        if ((stack_size(g->q->opque->qd.list) == 1) && (g->base.started_execution == 0)) {  //** See if we can directly exec
            log_printf(15, "sync_exec_que -- waiting for gid=%d to complete\n", gop_id(g));
            cb = (callback_t *)pop(g->q->opque->qd.list);
            g2 = (op_generic_t *)cb->priv;
            unlock_gop(g);  //** Don't need this for a direct exec
            status = gop_waitall(g2);
            log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), status);
            return(status);
        } else {  //** Got to submit it normally
            _gop_start_execution(g);  //** Make sure things have been submitted
            while (g->q->nleft > 0) {
                apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes
            }
        }
    } else {     //** Got a single task
        if ((g->base.pc->fn->sync_exec != NULL) && (g->base.started_execution == 0)) {  //** See if we can directly exec
            unlock_gop(g);  //** Don't need this for a direct exec
            log_printf(15, "sync_exec -- waiting for gid=%d to complete\n", gop_id(g));
            g->base.pc->fn->sync_exec(g->base.pc, g);
            status = _gop_completed_successfully(g);
            log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), status);
            return(status);
        } else {  //** Got to submit it the normal way
            _gop_start_execution(g);  //** Make sure things have been submitted
            while (g->base.state == 0) {
                log_printf(15, "gop_waitall: WHILE gid=%d state=%d\n", gop_id(g), g->base.state);
                apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes
            }
        }
    }

    status = _gop_completed_successfully(g);

    log_printf(15, "END gid=%d type=%d\n", gop_id(g), gop_get_type(g));
    unlock_gop(g);

    return(status);
}
Пример #2
0
op_generic_t *gop_timed_waitany(op_generic_t *g, int dt)
{
    op_generic_t *gop = NULL;
    apr_interval_time_t adt = apr_time_from_sec(dt);
    int loop;

    lock_gop(g);
    _gop_start_execution(g);  //** Make sure things have been submitted

    loop = 0;
    if (gop_get_type(g) == Q_TYPE_QUE) {
        while (((gop = (op_generic_t *)pop(g->q->finished)) == NULL) && (g->q->nleft > 0) && (loop == 0)) {
            apr_thread_cond_timedwait(g->base.ctl->cond, g->base.ctl->lock, adt); //** Sleep until something completes
            loop++;
        }
    } else {
        while ((g->base.state == 0) && (loop == 0)) {
            apr_thread_cond_timedwait(g->base.ctl->cond, g->base.ctl->lock, adt); //** Sleep until something completes
            loop++;
        }

        if (g->base.state != 0) gop = g;
    }
    unlock_gop(g);

    return(gop);
}
Пример #3
0
int gop_timed_waitall(op_generic_t *g, int dt)
{
    int status;
    int loop;
    apr_interval_time_t adt = apr_time_from_sec(dt);

    lock_gop(g);
    _gop_start_execution(g);  //** Make sure things have been submitted

    loop = 0;
    if (gop_get_type(g) == Q_TYPE_QUE) {
        while ((g->q->nleft > 0) && (loop == 0)) {
            apr_thread_cond_timedwait(g->base.ctl->cond, g->base.ctl->lock, adt); //** Sleep until something completes
            loop++;
        }

        status = (g->q->nleft > 0) ? OP_STATE_RETRY : _gop_completed_successfully(g);
    } else {
        while ((g->base.state == 0) && (loop == 0)) {
            apr_thread_cond_timedwait(g->base.ctl->cond, g->base.ctl->lock, adt); //** Sleep until something completes
            loop++;
        }

        status = (g->base.state == 0) ? OP_STATE_RETRY : _gop_completed_successfully(g);
    }

    unlock_gop(g);

    return(status);
}
Пример #4
0
void _gop_start_execution(op_generic_t *g)
{
    if (gop_get_type(g) == Q_TYPE_QUE) {
        _opque_start_execution(g->q->opque);
    } else if (g->base.started_execution == 0) {
        log_printf(15, "gid=%d started_execution=%d\n", gop_get_id(g), g->base.started_execution);
        g->base.started_execution = 1;
        g->base.pc->fn->submit(g->base.pc->arg, g);
    }
}
Пример #5
0
op_generic_t *gop_waitany(op_generic_t *g)
{
    op_generic_t *gop = g;
    callback_t *cb;

    lock_gop(g);

    if (gop_get_type(g) == Q_TYPE_QUE) {
        log_printf(15, "sync_exec_que_check gid=%d stack_size=%d started_exec=%d\n", gop_id(g), stack_size(g->q->opque->qd.list), g->base.started_execution);
        if ((stack_size(g->q->opque->qd.list) == 1) && (g->base.started_execution == 0)) {  //** See if we can directly exec
            g->base.started_execution = 1;
            cb = (callback_t *)pop(g->q->opque->qd.list);
            gop = (op_generic_t *)cb->priv;
            log_printf(15, "sync_exec_que -- waiting for pgid=%d cgid=%d to complete\n", gop_id(g), gop_id(gop));
            unlock_gop(g);
            gop_waitany(gop);
            pop(g->q->finished); //** Remove it from the finished list.
            return(gop);
        } else {
            _gop_start_execution(g);  //** Make sure things have been submitted
            while (((gop = (op_generic_t *)pop(g->q->finished)) == NULL) && (g->q->nleft > 0)) {
                apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes
            }
        }

        if (gop != NULL) log_printf(15, "POP finished qid=%d gid=%d\n", gop_id(g), gop_id(gop));
//log_printf(15, "Printing qid=%d finished stack\n", gop_id(g));
//_opque_print_stack(g->q->finished);
    } else {
        log_printf(15, "gop_waitany: BEFORE (type=op) While gid=%d state=%d\n", gop_id(g), g->base.state);
        flush_log();
        if ((g->base.pc->fn->sync_exec != NULL) && (g->base.started_execution == 0)) {  //** See if we can directly exec
            unlock_gop(g);  //** Don't need this for a direct exec
            log_printf(15, "sync_exec -- waiting for gid=%d to complete\n", gop_id(g));
            g->base.pc->fn->sync_exec(g->base.pc, g);
            log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(g), g->base.state);
            return(g);
        } else {  //** Got to submit it normally
            unlock_gop(g);  //** It's a single task so no need to hold the lock.  Otherwise we can deadlock
            _gop_start_execution(g);  //** Make sure things have been submitted
            lock_gop(g);  //** but we do need it for detecting when we're finished.
            while (g->base.state == 0) {
                apr_thread_cond_wait(g->base.ctl->cond, g->base.ctl->lock); //** Sleep until something completes
            }
        }
        log_printf(15, "gop_waitany: AFTER (type=op) While gid=%d state=%d\n", gop_id(g), g->base.state);
        flush_log();
    }
    unlock_gop(g);

    return(gop);
}
Пример #6
0
void gop_finished_submission(op_generic_t *g)
{
    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        g->q->finished_submission = 1;

        //** If nothing left to do trigger the condition in case anyone's waiting
        if (g->q->nleft == 0) {
            apr_thread_cond_broadcast(g->base.ctl->cond);
        }
    }
    unlock_gop(g);
}
Пример #7
0
int _gop_completed_successfully(op_generic_t *g)
{
    int status;

    if (gop_get_type(g) == Q_TYPE_QUE) {
        status = stack_size(g->q->failed);
        status = (status == 0) ? g->base.status.op_status : OP_STATE_FAILURE;
    } else {
        status = g->base.status.op_status;
    }

    return(status);
}
Пример #8
0
int gop_tasks_finished(op_generic_t *g)
{
    int nf;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        nf = stack_size(g->q->finished);
    } else {
        nf = (g->base.state == 1) ? 1 : 0;
    }
    unlock_gop(g);

    return(nf);
}
Пример #9
0
int gop_tasks_failed(op_generic_t *g)
{
    int nf;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        nf = stack_size(g->q->failed);
    } else {
        nf = (g->base.status.op_status == OP_STATE_SUCCESS) ? 0 : 1;
    }
    unlock_gop(g);

    return(nf);
}
Пример #10
0
int gop_tasks_left(op_generic_t *g)
{
    int n;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        n = g->q->nleft;
    } else {
        n = (g->base.state == 1) ? 0 : 1;
    }
    unlock_gop(g);

    return(n);
}
Пример #11
0
int gop_will_block(op_generic_t *g)
{
    int status = 0;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        if ((stack_size(g->q->finished) == 0) && (g->q->nleft > 0)) status = 1;
    } else {
        if (g->base.state == 0) status = 1;
    }
    unlock_gop(g);

    return(status);
}
Пример #12
0
void gop_free(op_generic_t *gop, int mode)
{
    int type;

    log_printf(15, "gop_free: gid=%d tid=%d\n", gop_id(gop), atomic_thread_id);
    //** Get the status
    type = gop_get_type(gop);
    if (type == Q_TYPE_QUE) {
        opque_free(gop->q->opque, mode);
    } else {
        //** the gop is locked in gop_generic_free before freeing
        gop->base.free(gop, mode);
    }
}
Пример #13
0
void _opque_print_stack(Stack_t *stack)
{
    op_generic_t *gop;
    int i=0;

    if (log_level() <= 15) return;

    move_to_top(stack);
    while ((gop = (op_generic_t *)get_ele_data(stack)) != NULL) {
        log_printf(15, "    i=%d gid=%d type=%d\n", i, gop_id(gop), gop_get_type(gop));
        i++;
        move_down(stack);
    }

    if (stack_size(stack) != i) log_printf(0, "Stack size mismatch! stack_size=%d i=%d\n", stack_size(stack), i);
}
Пример #14
0
op_generic_t *gop_get_next_failed(op_generic_t *g)
{
    op_generic_t *gop = NULL;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        gop = (op_generic_t *)pop(g->q->failed);
    } else {
        gop = NULL;
        if (g->base.failure_mode != OP_FM_GET_END) {
            g->base.failure_mode = OP_FM_GET_END;
            if (g->base.status.op_status != OP_STATE_SUCCESS) gop = g;
        }
    }
    unlock_gop(g);

    return(gop);
}
Пример #15
0
op_generic_t *gop_get_next_finished(op_generic_t *g)
{
    op_generic_t *gop;

    lock_gop(g);
    if (gop_get_type(g) == Q_TYPE_QUE) {
        gop = (op_generic_t *)pop(g->q->finished);
    } else {
        gop = NULL;
        if (g->base.failure_mode != OP_FM_GET_END) {
            g->base.failure_mode = OP_FM_GET_END;
            gop = g;
        }
    }
    unlock_gop(g);

    return(gop);
}
Пример #16
0
void _opque_cb(void *v, int mode)
{
    int type, n;
    op_status_t success;
    op_generic_t *gop = (op_generic_t *)v;
    que_data_t *q = &(gop->base.parent_q->qd);

    log_printf(15, "_opque_cb: START qid=%d gid=%d\n", gop_id(&(q->opque->op)), gop_id(gop));

    //** Get the status (gop is already locked)
    type = gop_get_type(gop);
    if (type == Q_TYPE_QUE) {
        n = stack_size(gop->q->failed);
        log_printf(15, "_opque_cb: qid=%d gid=%d  stack_size(q->failed)=%d gop->status=%d\n", gop_id(&(q->opque->op)), gop_id(gop), n, gop->base.status.op_status);
        success = (n == 0) ? gop->base.status : op_failure_status;
    } else {
        success = gop->base.status;
    }

    lock_opque(q);

    log_printf(15, "_opque_cb: qid=%d gid=%d success=%d gop_type(gop)=%d\n", gop_id(&(q->opque->op)), gop_id(gop), success, gop_get_type(gop));


    //** It always goes on the finished list
    move_to_bottom(q->finished);
    insert_below(q->finished, gop);

    log_printf(15, "PUSH finished gid=%d qid=%d\n", gop_id(gop), gop_id(&(q->opque->op)));
    log_printf(15, "Printing finished stack for qid=%d\n", gop_id(&(q->opque->op)));
    if (log_level() > 15) _opque_print_stack(q->finished);

    if (success.op_status == OP_STATE_FAILURE) push(q->failed, gop); //** Push it on the failed list if needed

    q->nleft--;
    log_printf(15, "_opque_cb: qid=%d gid=%d nleft=%d stack_size(q->failed)=%d stack_size(q->finished)=%d\n", gop_id(&(q->opque->op)), gop_id(gop), q->nleft, stack_size(q->failed), stack_size(q->finished));
    flush_log();

    if (q->nleft <= 0) {  //** we're finished
        if (stack_size(q->failed) == 0) {
            q->opque->op.base.status = op_success_status;
            callback_execute(q->opque->op.base.cb, OP_STATE_SUCCESS);

            //** Lastly trigger the signal. for anybody listening
            apr_thread_cond_broadcast(q->opque->op.base.ctl->cond);
        } else if (q->opque->op.base.retries == 0) {  //** How many times we're retried
            //** Trigger the callbacks
            q->opque->op.base.retries++;
            q->nleft = 0;
            q->opque->op.base.failure_mode = 0;
            callback_execute(&(q->failure_cb), OP_STATE_FAILURE);  //** Attempt to fix things

            if (q->opque->op.base.failure_mode == 0) {  //** No retry
                q->opque->op.base.status = op_failure_status;
                callback_execute(q->opque->op.base.cb, OP_STATE_FAILURE);  //**Execute the other CBs
                apr_thread_cond_broadcast(q->opque->op.base.ctl->cond);  //** and fail for good
            }

            //** If retrying don't send the broadcast
            log_printf(15, "_opque_cb: RETRY END qid=%d gid=%d\n", gop_id(&(q->opque->op)), gop_id(gop));
            flush_log();
        } else {
            //** Finished with errors but trigger the signal for anybody listening
            apr_thread_cond_broadcast(q->opque->op.base.ctl->cond);
        }
    } else {
        //** Not finished but trigger the signal for anybody listening
        apr_thread_cond_broadcast(q->opque->op.base.ctl->cond);
    }

    log_printf(15, "_opque_cb: END qid=%d gid=%d\n", gop_id(&(q->opque->op)), gop_id(gop));
    flush_log();

    unlock_opque(q);
}
Пример #17
0
void gop_set_exec_mode(op_generic_t *g, int mode)
{
    if (gop_get_type(g) == Q_TYPE_OPERATION) {
        g->base.execution_mode = mode;
    }
}