Exemple #1
0
op_status_t gop_sync_exec_status(op_generic_t *gop)
{
    int err;
    op_status_t status;

    if (gop->type == Q_TYPE_OPERATION) { //** Got an operation so see if we can directly exec it
        if (gop->base.pc->fn->sync_exec != NULL) {  //** Yup we can!
            log_printf(15, "sync_exec -- waiting for gid=%d to complete\n", gop_id(gop));
            gop->base.pc->fn->sync_exec(gop->base.pc, gop);
            status = gop->base.status;
            log_printf(15, "sync_exec -- gid=%d completed with err=%d\n", gop_id(gop), status.op_status);
            gop_free(gop, OP_DESTROY);
            return(status);
        }
    }

    log_printf(15, "waiting for gid=%d to complete\n", gop_id(gop));
    err = gop_waitall(gop);
    status = gop_get_status(gop);
    log_printf(15, "gid=%d completed with err=%d\n", gop_id(gop), err);
    gop_free(gop, OP_DESTROY);
    log_printf(15, "After gop destruction\n");

    return(status);
}
Exemple #2
0
void _opque_start_execution(opque_t *que)
{
    int n, i;
    callback_t *cb;
    op_generic_t *gop;
    que_data_t *q = &(que->qd);

    gop = opque_get_gop(que);
    if (gop->base.started_execution != 0) {
        return;
    }

    gop->base.started_execution = 1;

    n = stack_size(q->list);
    move_to_top(q->list);
    for (i=0; i<n; i++) {
        cb = (callback_t *)pop(q->list);
        gop = (op_generic_t *)cb->priv;
        if (gop->type == Q_TYPE_OPERATION) {
            log_printf(15, "qid=%d gid=%d\n",gop_id(opque_get_gop(que)), gop_get_id(gop));
            gop->base.started_execution = 1;
            gop->base.pc->fn->submit(gop->base.pc->arg, gop);
        } else {  //** It's a queue
            log_printf(15, "qid=%d Q gid=%d\n",gop_id(opque_get_gop(que)), gop_get_id(gop));
            lock_opque(gop->q);
            _opque_start_execution(gop->q->opque);
            unlock_opque(gop->q);
        }
    }

//  unlock_opque(q);
}
Exemple #3
0
void single_gop_mark_completed(op_generic_t *gop, op_status_t status)
{
    op_common_t *base = &(gop->base);
    int mode;

    log_printf(15, "gop_mark_completed: START gid=%d status=%d\n", gop_id(gop), status.op_status);

    lock_gop(gop);
    log_printf(15, "gop_mark_completed: after lock gid=%d\n", gop_id(gop));

    //** Store the status
    base->status = status;

    //** and trigger any callbacks

    log_printf(15, "gop_mark_completed: before cb gid=%d op_status=%d\n", gop_id(gop), base->status.op_status);

    callback_execute(base->cb, base->status.op_status);

    log_printf(15, "gop_mark_completed: after cb gid=%d op_success=%d\n", gop_id(gop), base->status.op_status);

    base->state = 1;

    //** Lastly trigger the signal. for anybody listening
    apr_thread_cond_broadcast(gop->base.ctl->cond);

    log_printf(15, "gop_mark_completed: after brodcast gid=%d\n", gop_id(gop));

    mode = gop_get_auto_destroy(gop);  //** Get the auto destroy status w/in the lock

    unlock_gop(gop);

    //** Check if we do an auto cleanop
    if (mode == 1) gop_free(gop, OP_DESTROY);
}
void mq_stream_read_destroy(mq_stream_t *mqs)
{

    log_printf(1, "START msid=%d\n", mqs->msid);

    if (mqs->mpool == NULL) {  //** Nothing to do
        pack_destroy(mqs->pack);
        if (mqs->stream_id != NULL) free(mqs->stream_id);
        free(mqs);
        return;
    }

    //** Change the flag which signals we don't want anything else
    apr_thread_mutex_lock(mqs->lock);
    mqs->want_more = MQS_ABORT;

    //** Consume all the current data and request the pending
    while ((mqs->gop_processed != NULL) || (mqs->gop_waiting != NULL)) {
        log_printf(1, "Clearing pending processed=%d waiting=%p msid=%d\n", mqs->gop_processed, mqs->gop_waiting, mqs->msid);
        if (mqs->gop_processed != NULL) log_printf(1, "processed gid=%d\n", gop_id(mqs->gop_processed));
        if (mqs->gop_waiting != NULL) log_printf(1, "waiting gid=%d\n", gop_id(mqs->gop_waiting));
        mqs->want_more = MQS_ABORT;
        apr_thread_mutex_unlock(mqs->lock);
        mq_stream_read_wait(mqs);
        apr_thread_mutex_lock(mqs->lock);
    }

    if (log_level() >= 15) {
        char *rhost = mq_address_to_string(mqs->remote_host);
        log_printf(15, "remote_host as string = %s\n", rhost);
        if (rhost) free(rhost);
    }
    if (mqs->remote_host != NULL) mq_ongoing_host_dec(mqs->ongoing, mqs->remote_host, mqs->host_id, mqs->hid_len);

    apr_thread_mutex_unlock(mqs->lock);

    log_printf(2, "msid=%d transfer_packets=%d\n", mqs->msid, mqs->transfer_packets);

    //** Clean up
    if (mqs->stream_id != NULL) free(mqs->stream_id);
    pack_destroy(mqs->pack);
    apr_thread_mutex_destroy(mqs->lock);
    apr_thread_cond_destroy(mqs->cond);
    apr_pool_destroy(mqs->mpool);
    if (mqs->remote_host != NULL) mq_msg_destroy(mqs->remote_host);
    free(mqs);

    return;
}
Exemple #5
0
void init_opque(opque_t *q)
{
    que_data_t *que = &(q->qd);
    op_generic_t *gop = &(q->op);

    type_memclear(q, opque_t, 1);

    gop_init(gop);

    log_printf(15, "init_opque: qid=%d\n", gop_id(gop));

    //**Set up the pointers
    gop->q = que;
    gop->q->opque = q;

    q->op.type = Q_TYPE_QUE;

    que->list = new_stack();
    que->finished = new_stack();
    que->failed = new_stack();
    que->nleft = 0;
    que->nsubmitted = 0;
    gop->base.retries = 0;
//  que->started_execution = 0;
    que->finished_submission = 0;
//  que->success = OP_STATE_FAILURE;
//  que->success = 12345;
}
Exemple #6
0
void _gop_dummy_submit_op(void *arg, op_generic_t *op)
{
    int dolock = 0;

    log_printf(15, "gid=%d\n", gop_id(op));
//  if (op->base.cb != NULL) {  //** gop is on a q
    apr_thread_mutex_lock(gd_lock);
    push(gd_stack, op);
    apr_thread_cond_signal(gd_cond);
    apr_thread_mutex_unlock(gd_lock);
    return;
//  }

//*-------* This isn't executed below -----------

    if (apr_thread_mutex_trylock(op->base.ctl->lock) != APR_SUCCESS) dolock = 1;
    unlock_gop(op);

//log_printf(15, "dolock=%d gid=%d err=%d APR_SUCCESS=%d\n", dolock, gop_id(op), err, APR_SUCCESS);
    op->base.started_execution = 1;
    gop_mark_completed(op, op->base.status);

    if (dolock == 1) {
        lock_gop(op);
    } //** lock_gop is a macro so need the {}
    return;
}
Exemple #7
0
void _tp_op_free(gop_op_generic_t *gop, int mode)
{
    gop_thread_pool_op_t *top = gop_get_tp(gop);
    int id = gop_id(gop);

    log_printf(15, "_tp_op_free: mode=%d gid=%d gop=%p\n", mode, gop_id(gop), gop);
    tbx_log_flush();

    if (top->my_op_free != NULL) top->my_op_free(top->arg);

    gop_generic_free(gop, OP_FINALIZE);  //** I free the actual op

    if (top->dop.cmd.hostport) free(top->dop.cmd.hostport);

    if (mode == OP_DESTROY) free(gop->free_ptr);
    log_printf(15, "_tp_op_free: gid=%d END\n", id);
    tbx_log_flush();

}
Exemple #8
0
void _tp_submit_op(void *arg, gop_op_generic_t *gop)
{
    gop_thread_pool_op_t *op = gop_get_tp(gop);
    apr_status_t aerr;
    int running;

    log_printf(15, "_tp_submit_op: gid=%d\n", gop_id(gop));

    tbx_atomic_inc(op->tpc->n_submitted);
    op->via_submit = 1;
    running = tbx_atomic_inc(op->tpc->n_running) + 1;

    if (running > op->tpc->max_concurrency) {
        apr_thread_mutex_lock(_tp_lock);
        tbx_atomic_inc(op->tpc->n_overflow);
        if (op->depth >= op->tpc->recursion_depth) {  //** Check if we hit the max recursion
            log_printf(0, "GOP has a recursion depth >= max specified in the TP!!!! gop depth=%d  TPC max=%d\n", op->depth, op->tpc->recursion_depth);
            tbx_stack_push(op->tpc->reserve_stack[op->tpc->recursion_depth-1], gop);  //** Need to do the push and overflow check
        } else {
            tbx_stack_push(op->tpc->reserve_stack[op->depth], gop);  //** Need to do the push and overflow check
        }
        gop = _tpc_overflow_next(op->tpc);             //** along with the submit or rollback atomically

        if (gop) {
            op = gop_get_tp(gop);
            aerr = apr_thread_pool_push(op->tpc->tp,(void *(*)(apr_thread_t *, void *))thread_pool_exec_fn, gop, APR_THREAD_TASK_PRIORITY_NORMAL, NULL);
        } else {
            tbx_atomic_dec(op->tpc->n_running);  //** We didn't actually submit anything
            if (op->overflow_slot != -1) {   //** Check if we need to undo our overflow slot
                op->tpc->overflow_running_depth[op->overflow_slot] = -1;
            }

            aerr = APR_SUCCESS;
        }
        apr_thread_mutex_unlock(_tp_lock);
    } else {
        aerr = apr_thread_pool_push(op->tpc->tp, (void *(*)(apr_thread_t *, void *))thread_pool_exec_fn, gop, APR_THREAD_TASK_PRIORITY_NORMAL, NULL);
    }

    if (aerr != APR_SUCCESS) {
        log_printf(0, "ERROR submiting task!  aerr=%d gid=%d\n", aerr, gop_id(gop));
    }
}
Exemple #9
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);
}
Exemple #10
0
int gop_wait(op_generic_t *gop)
{
    op_status_t status;
//log_printf(15, "gop_wait: START gid=%d state=%d\n", gop_id(gop), gop->base.state);

    lock_gop(gop);

//log_printf(15, "gop_wait: after lock gid=%d state=%d\n", gop_id(gop), gop->base.state);

    while (gop->base.state == 0) {
        log_printf(15, "gop_wait: WHILE gid=%d state=%d\n", gop_id(gop), gop->base.state);
        apr_thread_cond_wait(gop->base.ctl->cond, gop->base.ctl->lock); //** Sleep until something completes
    }

    status = gop_get_status(gop);
//  state = _gop_completed_successfully(gop);
    log_printf(15, "gop_wait: FINISHED gid=%d status=%d err=%d\n", gop_id(gop), status.op_status, status.error_code);

    unlock_gop(gop);

    return(status.op_status);
}
Exemple #11
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);
    }
}
Exemple #12
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);
}
Exemple #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);
}
Exemple #14
0
void gop_init(op_generic_t *gop)
{
    pigeon_coop_hole_t pch;

    op_common_t *base = &(gop->base);

    type_memclear(gop, op_generic_t, 1);

    base->id = atomic_global_counter();

    log_printf(15, "gop ptr=%p gid=%d\n", gop, gop_id(gop));

    //** Get the control struct
    pch = reserve_pigeon_coop_hole(_gop_control);
    gop->base.ctl = (gop_control_t *)pigeon_coop_hole_data(&pch);
    gop->base.ctl->pch = pch;
}
Exemple #15
0
void opque_free(opque_t *opq, int mode)
{
    que_data_t *q = &(opq->qd);

    log_printf(15, "qid=%d nfin=%d nlist=%d nfailed=%d\n", gop_id(&(opq->op)), stack_size(q->finished), stack_size(q->list), stack_size(q->failed));

    lock_opque(&(opq->qd));  //** Lock it to make sure Everything is finished and safe to free

    //** Free the stacks
    free_stack(q->failed, 0);
    free_finished_stack(q->finished, mode);
    free_list_stack(q->list, mode);

    unlock_opque(&(opq->qd));  //** Has to be unlocked for gop_generic_free to work cause it also locks it
    gop_generic_free(opque_get_gop(opq), mode);

    if (mode == OP_DESTROY) free(opq);
}
Exemple #16
0
void *gd_thread_func(apr_thread_t *th, void *data)
{
    op_generic_t *gop;

    apr_thread_mutex_lock(gd_lock);
    while (gd_shutdown == 0) {
        //** Execute everything on the stack
        while ((gop = (op_generic_t *)pop(gd_stack)) != NULL) {
            log_printf(15, "DUMMY gid=%d status=%d\n", gop_id(gop), gop->base.status.op_status);
            apr_thread_mutex_unlock(gd_lock);
            gop_mark_completed(gop, gop->base.status);
            apr_thread_mutex_lock(gd_lock);
        }

        //** Wait for more work
        apr_thread_cond_wait(gd_cond, gd_lock);
    }
    apr_thread_mutex_unlock(gd_lock);

    return(NULL);
}
Exemple #17
0
void free_list_stack(Stack_t *stack, int mode)
{
    op_generic_t *gop;
    callback_t *cb;

    cb = (callback_t *)pop(stack);
    while (cb != NULL) {
        gop = (op_generic_t *)cb->priv;
        log_printf(15, "gid=%d\n", gop_id(gop));
        if (gop->type == Q_TYPE_QUE) {
//log_printf(15, "free_opque_stack: gop->type=QUE\n"); flush_log();
            opque_free(gop->q->opque, mode);
        } else {
//log_printf(15, "free_opque_stack: gop->type=OPER\n"); flush_log();
//DONE in op_generic_destroy        callback_destroy(gop->base.cb);  //** Free the callback chain as well
            if (gop->base.free != NULL) gop->base.free(gop, mode);
        }

        cb = (callback_t *)pop(stack);
    }

    free_stack(stack, 0);
}
void *ongoing_heartbeat_thread(apr_thread_t *th, void *data)
{
    mq_ongoing_t *on = (mq_ongoing_t *)data;
    apr_time_t timeout = apr_time_make(on->check_interval, 0);
    op_generic_t *gop;
    mq_msg_t *msg;
    ongoing_hb_t *oh;
    ongoing_table_t *table;
    apr_hash_index_t *hi, *hit;
    opque_t *q;
    char *id;
    mq_msg_hash_t *remote_hash;
    apr_time_t now;
    apr_ssize_t id_len;
    int n, k;
    char *remote_host_string;

    apr_thread_mutex_lock(on->lock);
    n = 0;
    do {
        now = apr_time_now() - apr_time_from_sec(5);  //** Give our selves a little buffer
        log_printf(5, "Loop Start now=" TT "\n", apr_time_now());
        q = new_opque();
//     opque_start_execution(q);
        for (hit = apr_hash_first(NULL, on->table); hit != NULL; hit = apr_hash_next(hit)) {
            apr_hash_this(hit, (const void **)&remote_hash, &id_len, (void **)&table);

            k = apr_hash_count(table->table);
            if (log_level() > 1) {
                remote_host_string = mq_address_to_string(table->remote_host);
                log_printf(1, "host=%s count=%d\n", remote_host_string, k);
                free(remote_host_string);
            }

            for (hi = apr_hash_first(NULL, table->table); hi != NULL; hi = apr_hash_next(hi)) {
                apr_hash_this(hi, (const void **)&id, &id_len, (void **)&oh);
                log_printf(1, "id=%s now=" TT " next_check=" TT "\n", oh->id, apr_time_sec(apr_time_now()), apr_time_sec(oh->next_check));
                if (now > oh->next_check) {
                    log_printf(1, "id=%s sending HEARTBEAT EXEC SUBMIT nows=" TT " hb=%d\n", oh->id, apr_time_sec(apr_time_now()), oh->heartbeat);
                    flush_log();
                    //** Form the message
                    msg = mq_make_exec_core_msg(table->remote_host, 1);
                    mq_msg_append_mem(msg, ONGOING_KEY, ONGOING_SIZE, MQF_MSG_KEEP_DATA);
                    mq_msg_append_mem(msg, oh->id, oh->id_len, MQF_MSG_KEEP_DATA);
                    mq_msg_append_mem(msg, NULL, 0, MQF_MSG_KEEP_DATA);

                    //** Make the gop
                    gop = new_mq_op(on->mqc, msg, ongoing_response_status, NULL, NULL, oh->heartbeat);
                    gop_set_private(gop, table);
                    opque_add(q, gop);

                    oh->in_progress = 1; //** Flag it as in progress so it doesn't get deleted behind the scenes
                }
            }

        }
        log_printf(5, "Loop end now=" TT "\n", apr_time_now());

        //** Wait for it to complete
        apr_thread_mutex_unlock(on->lock);
        opque_waitall(q);
        apr_thread_mutex_lock(on->lock);

        //** Dec the counters
        while ((gop = opque_waitany(q)) != NULL) {
            log_printf(0, "gid=%d gotone status=%d now=" TT "\n", gop_id(gop), (gop_get_status(gop)).op_status, apr_time_sec(apr_time_now()));
            table = gop_get_private(gop);
            table->count--;

            //** Update the next check
            for (hi = apr_hash_first(NULL, table->table); hi != NULL; hi = apr_hash_next(hi)) {
                apr_hash_this(hi, (const void **)&id, &id_len, (void **)&oh);
                oh->next_check = apr_time_now() + apr_time_from_sec(oh->heartbeat);

                //** Check if we get rid of it
                oh->in_progress = 0;
                if (oh->count <= 0) {  //** Need to delete it
                    apr_hash_set(table->table, id, id_len, NULL);
                    free(oh->id);
                    free(oh);
                }
            }

            gop_free(gop, OP_DESTROY);
        }
        opque_free(q, OP_DESTROY);

        now = apr_time_now();
        log_printf(2, "sleeping %d now=" TT "\n", on->check_interval, now);

        //** Sleep until time for the next heartbeat or time to exit
        if (on->shutdown == 0) apr_thread_cond_timedwait(on->cond, on->lock, timeout);
        n = on->shutdown;

        now = apr_time_now() - now;
        log_printf(2, "main loop bottom n=%d dt=" TT " sec=" TT "\n", n, now, apr_time_sec(now));
    } while (n == 0);

    log_printf(2, "CLEANUP\n");

    for (hit = apr_hash_first(NULL, on->table); hit != NULL; hit = apr_hash_next(hit)) {
        apr_hash_this(hit, (const void **)&remote_hash, &id_len, (void **)&table);

        for (hi = apr_hash_first(NULL, table->table); hi != NULL; hi = apr_hash_next(hi)) {
            apr_hash_this(hi, (const void **)&id, &id_len, (void **)&oh);
            apr_hash_set(table->table, id, id_len, NULL);
            free(oh->id);
            free(oh);
        }

        apr_hash_set(on->table, &(table->remote_host_hash), sizeof(mq_msg_hash_t), NULL);
        mq_msg_destroy(table->remote_host);
        free(table);
    }

    log_printf(2, "EXITING\n");

    apr_thread_mutex_unlock(on->lock);

    return(NULL);
}
void _zsock_submit_op(void *arg, op_generic_t *gop)
{
    portal_context_t *pc = gop->base.pc;

    log_printf(15, "_zsock_submit_op: hpc=%p hpc->table=%p gop=%p gid=%d\n", pc, pc->table, gop, gop_id(gop));

    if (gop->base.execution_mode == OP_EXEC_DIRECT) {
        submit_hp_direct_op(pc, gop);
    } else {
        submit_hp_que_op(pc, gop);
    }
}
Exemple #20
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);
}
int mq_stream_read_wait(mq_stream_t *mqs)
{
    int err = 0;
    apr_interval_time_t dt;
    op_status_t status;

    //** If 1st time make all the variables
    if (mqs->mpool == NULL) {
        apr_pool_create(&mqs->mpool, NULL);
        apr_thread_mutex_create(&(mqs->lock), APR_THREAD_MUTEX_DEFAULT, mqs->mpool);
        apr_thread_cond_create(&(mqs->cond), mqs->mpool);
    }

    dt = apr_time_from_sec(1);


    //** Flag the just processed gop to clean up
    apr_thread_mutex_lock(mqs->lock);
    log_printf(5, "START msid=%d waiting=%d processed=%d gop_processed=%p\n", mqs->msid, mqs->waiting, mqs->processed, mqs->gop_processed);
    if (mqs->gop_processed != NULL) mqs->processed = 1;
    apr_thread_cond_broadcast(mqs->cond);

    if (mqs->data) {
        if (mqs->data[MQS_STATE_INDEX] != MQS_MORE) err = 1;
    }
    apr_thread_mutex_unlock(mqs->lock);

    if (mqs->gop_processed != NULL) {
        gop_waitany(mqs->gop_processed);
        gop_free(mqs->gop_processed, OP_DESTROY);
        mqs->gop_processed = NULL;
    }

    if (err != 0) {
        log_printf(2, "ERROR no more data available!\n");
        return(-1);
    }

    //** Now handle the waiting gop
    apr_thread_mutex_lock(mqs->lock);
    log_printf(5, "before loop msid=%d waiting=%d processed=%d\n", mqs->msid, mqs->waiting, mqs->processed);

    while (mqs->waiting == 1) {
        log_printf(5, "LOOP msid=%d waiting=%d processed=%d\n", mqs->msid, mqs->waiting, mqs->processed);
        if (gop_will_block(mqs->gop_waiting) == 0)  { //** Oops!  failed request
            status = gop_get_status(mqs->gop_waiting);
            log_printf(2, "msid=%d gid=%d status=%d\n", mqs->msid, gop_id(mqs->gop_waiting), status.op_status);
            if (status.op_status != OP_STATE_SUCCESS) {
                mqs->waiting = -3;
                err = 1;
            } else {
                apr_thread_cond_timedwait(mqs->cond, mqs->lock, dt);
            }
        } else {
            apr_thread_cond_timedwait(mqs->cond, mqs->lock, dt);
        }
    }

    if (mqs->waiting == 0) {  //** Flag the receiver to accept the data
        mqs->waiting = -1;
        apr_thread_cond_broadcast(mqs->cond);  //** Let the receiver know we're ready to accept the data

        //** Wait for the data to be accepted
        while (mqs->waiting != -2) {
            apr_thread_cond_wait(mqs->cond, mqs->lock);
        }
    } else if (mqs->waiting == -3) { //**error occured
        err = 1;
    }
    apr_thread_mutex_unlock(mqs->lock);

    //** Flip states
    mqs->gop_processed = mqs->gop_waiting;
    mqs->gop_waiting = NULL;

    //** This shouldn't get triggered but just in case lets throw an error.
    if ((mqs->gop_processed == NULL) && (mqs->data != NULL)) {
        if ((mqs->data[MQS_STATE_INDEX] == MQS_MORE) && (mqs->want_more == MQS_MORE)) {
            err = 3;
            log_printf(0, "ERROR: MQS gop processed=waiting=NULL  want_more set!!!!!! err=%d\n", err);
            fprintf(stderr, "ERROR: MQS gop processed=waiting=NULL want_more set!!!!!! err=%d\n", err);
        }
    }

    //** Check if we need to fire off the next request
    if (mqs->data != NULL) {
        if ((mqs->data[MQS_STATE_INDEX] == MQS_MORE) && (mqs->want_more == MQS_MORE)) {
            mq_stream_read_request(mqs);
        }
    }

    log_printf(5, "err=%d\n", err);
    return(err);
}