Ejemplo n.º 1
0
int
ub_wait(struct ub_ctx* ctx)
{
    int err;
    ub_callback_t cb;
    void* cbarg;
    struct ub_result* res;
    int r;
    uint8_t* msg;
    uint32_t len;
    /* this is basically the same loop as _process(), but with changes.
     * holds the rrpipe lock and waits with tube_wait */
    while(1) {
        lock_basic_lock(&ctx->rrpipe_lock);
        lock_basic_lock(&ctx->cfglock);
        if(ctx->num_async == 0) {
            lock_basic_unlock(&ctx->cfglock);
            lock_basic_unlock(&ctx->rrpipe_lock);
            break;
        }
        lock_basic_unlock(&ctx->cfglock);

        /* keep rrpipe locked, while
         * 	o waiting for pipe readable
         * 	o parsing message
         * 	o possibly decrementing num_async
         * do callback without lock
         */
        r = tube_wait(ctx->rr_pipe);
        if(r) {
            r = tube_read_msg(ctx->rr_pipe, &msg, &len, 1);
            if(r == 0) {
                lock_basic_unlock(&ctx->rrpipe_lock);
                return UB_PIPE;
            }
            if(r == -1) {
                lock_basic_unlock(&ctx->rrpipe_lock);
                continue;
            }
            r = process_answer_detail(ctx, msg, len,
                                      &cb, &cbarg, &err, &res);
            lock_basic_unlock(&ctx->rrpipe_lock);
            free(msg);
            if(r == 0)
                return UB_PIPE;
            if(r == 2)
                (*cb)(cbarg, err, res);
        } else {
            lock_basic_unlock(&ctx->rrpipe_lock);
        }
    }
    return UB_NOERROR;
}
Ejemplo n.º 2
0
int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len, 
        int nonblock)
{
	struct tube_res_list* item = NULL;
	verbose(VERB_ALGO, "tube read_msg %s", nonblock?"nonblock":"blocking");
	*buf = NULL;
	if(!tube_poll(tube)) {
		verbose(VERB_ALGO, "tube read_msg nodata");
		/* nothing ready right now, wait if we want to */
		if(nonblock)
			return -1; /* would block waiting for items */
		if(!tube_wait(tube))
			return 0;
	}
	lock_basic_lock(&tube->res_lock);
	if(tube->res_list) {
		item = tube->res_list;
		tube->res_list = item->next;
		if(tube->res_last == item) {
			/* the list is now empty */
			tube->res_last = NULL;
			verbose(VERB_ALGO, "tube read_msg lastdata");
			if(!WSAResetEvent(tube->event)) {
				log_err("WSAResetEvent: %s", 
					wsa_strerror(WSAGetLastError()));
			}
		}
	}
	lock_basic_unlock(&tube->res_lock);
	if(!item)
		return 0; /* would block waiting for items */
	*buf = item->buf;
	*len = item->len;
	free(item);
	verbose(VERB_ALGO, "tube read_msg len %d", (int)*len);
	return 1;
}