Esempio n. 1
0
int
chanrecv(Channel *c, void *v)
{
	while (1)
	{
		int result = channbrecv(c, v);
		if (result != LTCHAN_NONE)
			return result;

		lthread_cond_wait(c->rcond, 0);
	}
}
Esempio n. 2
0
static int
memqueue_poll_queue(poll_args_t *user_args)
{

    int rev = 0;
    int i = 0;
    int total_msgs = 0;
    int total_bound_queues = 0;

    cli_binder_t *cli_binder = NULL;
    memqueue_t *q = NULL;

    cli_binder = cli_binder_create(user_args->timeout);
    for (i = 0; i < user_args->total; i++) {

        q = h_get(memqueue_ins.queue_store, user_args->queue_args[i].q_id);

        if (!q)
            continue;

        total_bound_queues++;

        if (q->consumer_expiry && user_args->queue_args[i].consumer_id != NULL)
            memqueue_refresh_consumer(q, user_args->queue_args[i].consumer_id);

        memqueue_resched(&memqueue_ins, q);

        //printf("q->rev is %d and user_rev is %d\n", q->rev, user_args->queue_args[i].rev);
        if (q->rev < user_args->queue_args[i].rev)
            rev = -1;
        else
            rev = user_args->queue_args[i].rev;

        /* bind poller */
        memqueue_bind(q, cli_binder, rev,
            user_args->queue_args[i].include_consumers);

        total_msgs += cli_binder_enqueue_msgs(cli_binder, q, rev,
            user_args->queue_args[i].latest);

    }

    if (total_bound_queues == 0) {
        cli_binder_free(cli_binder);
        memqueue_respond(MEMQUEUE_NOT_FOUND, NULL);
        return 0;
    }

    /* Do we have messages that match our rev requirements already? */
    if (total_msgs == 0)
        lthread_cond_wait(cli_binder->cond, cli_binder->timeout);

    if (cli_binder_has_pending_msgs(cli_binder))
        memqueue_respond(MEMQUEUE_MSGS, cli_binder);
    else
        memqueue_respond(MEMQUEUE_TIMEOUT, NULL);

    memqueue_unbind_all(cli_binder);
    cli_binder_release_pending_msgs(cli_binder);
    cli_binder_free(cli_binder);

    return 0;
}
Esempio n. 3
0
int
_chansend(Channel *c, void *v, int block)
{
	if (c->closed)
		return LTCHAN_CLOSED;

	// special condition for 0
	// if the buffer size is 0 (synchronous), then we will go over the 
	// the buffer limit regardless... (and block later until chan receieves it)

	while (1)
	{
		int cond = (c->cursize >= c->bufsize);
		if (c->bufsize == 0)
			cond = (c->cursize > c->bufsize);

		if (!cond) {
			break;
		}

		if (block) {
			lthread_cond_wait(c->wcond, 0);
		} else {
			return LTCHAN_FULL;
		}
	}

	// check again in case we close the channel
	if (c->closed)
		return LTCHAN_CLOSED;

	_lt_ch_list *elem = malloc(sizeof(_lt_ch_list));
	elem->prev = c->tail;
	elem->elem = malloc(c->elemsize);
	memmove(elem->elem, v, c->elemsize);
	elem->next = NULL;

	if (c->head == NULL) { // no elements
		c->head = elem;
		c->tail = elem;
	} else {
		c->tail->next = elem;
		c->tail = elem;
	}

	c->cursize++;

	// let readers know that we've just inserted an element
	lthread_cond_broadcast(c->rcond);

	// if buffer is overfull and we're blocking, block
	// (special condition for 0: block always)
	if (block || c->bufsize == 0)
	{
		while (c->cursize > c->bufsize)
		{
			lthread_cond_wait(c->wcond, 0);
		}
	}

	return 0;
}