예제 #1
0
/* Must be called with nklock locked irqs off */
int __xnselect_signal(struct xnselect *select_block, unsigned state)
{
	xnholder_t *holder;
	int resched;

	for(resched = 0, holder = getheadq(&select_block->bindings);
	    holder; holder = nextq(&select_block->bindings, holder)) {
		struct xnselect_binding *binding;
		struct xnselector *selector;

		binding = link2binding(holder, link);

		selector = binding->selector;
		if (state) {
			if (!__FD_ISSET(binding->bit_index,
					&selector->fds[binding->type].pending)) {
				__FD_SET(binding->bit_index,
					 &selector->fds[binding->type].pending);
				if (xnselect_wakeup(selector))
					resched = 1;
			}
		} else
			__FD_CLR(binding->bit_index,
				 &selector->fds[binding->type].pending);
	}

	return resched;
}
예제 #2
0
/**
 * Destroy the @a xnselect structure associated with a file descriptor.
 *
 * Any binding with a @a xnselector block is destroyed.
 *
 * @param select_block pointer to the @a xnselect structure associated with a file descriptor
 */
void xnselect_destroy(struct xnselect *select_block)
{
	xnholder_t *holder;
	int resched = 0;
	spl_t s;

	xnlock_get_irqsave(&nklock, s);
	while ((holder = getq(&select_block->bindings))) {
		struct xnselect_binding *binding;
		struct xnselector *selector;

		binding = link2binding(holder, link);
		selector = binding->selector;

		__FD_CLR(binding->bit_index,
			 &selector->fds[binding->type].expected);
		if (!__FD_ISSET(binding->bit_index,
				&selector->fds[binding->type].pending)) {
			__FD_SET(binding->bit_index,
				 &selector->fds[binding->type].pending);
			if (xnselect_wakeup(selector))
				resched = 1;
		}
		removeq(&selector->bindings, &binding->slink);
		xnlock_put_irqrestore(&nklock, s);

		xnfree(binding);

		xnlock_get_irqsave(&nklock, s);
	}
	if (resched)
		xnpod_schedule();
	xnlock_put_irqrestore(&nklock, s);
}
예제 #3
0
static int exa_select(struct exa_select *sel)
{
    int i;
    int one=0;
    int ret = -EFAULT;

    /* first phase register on each queue */
    for (i = 0; i < __FD_SETSIZE; i++)
    {
        __FD_CLR(i, &sel->result);
        if (__FD_ISSET(i, &sel->select))
        {
            sel->elt[i].socket = exa_getsock(i);
            if (sel->elt[i].socket == NULL)
            {
                ret  = -EINVAL;
                continue;
            }

            set_callbacks(sel->elt[i].socket, &sel->elt[i]);
            if (sel->operation == EXA_SELECT_IN)
            {
                if (sock_readable(sel->elt[i].socket) == 1)
                one = 1;
            }

            if (sel->operation == EXA_SELECT_OUT)
                if (sock_writable(sel->elt[i].socket) == 1)
                    one = 1;
        }
    }

    /* second phase : check if nothing arrived and wait if nothing arrived */
    if (one==0)
    {
        int timeout = SELECT_TIMEOUT ;

        set_current_state(TASK_INTERRUPTIBLE);
        for (i = 0; i < __FD_SETSIZE; i++)
        {
            if (__FD_ISSET(i, &sel->select) && (sel->elt[i].socket != NULL))
            {
                if (sel->operation == EXA_SELECT_IN)
                {
                    if (sock_readable(sel->elt[i].socket) == 1)
                    one = 1;
                }

                if (sel->operation == EXA_SELECT_OUT)
                {
                    if (sock_writable(sel->elt[i].socket) == 1)
                    one = 1;
                }
            }
        }

        if (one == 0) /* if some data already pending, we must not wait (or some race can occur)*/
            timeout = schedule_timeout(timeout);

        set_current_state(TASK_RUNNING);
    }

    /* third : find wich socket receive/sent something */
    for (i = __FD_SETSIZE - 1; i >= 0; i--)
    {
        if (__FD_ISSET(i, &sel->select))
        {
            if (sel->elt[i].socket == NULL)
                continue;
            if (sel->operation == EXA_SELECT_IN)
            {
                if (sock_readable(sel->elt[i].socket) == 1)
                __FD_SET(i, &sel->result);
            }

            if (sel->operation == EXA_SELECT_OUT)
            {
                if (sock_writable(sel->elt[i].socket) == 1)
                __FD_SET(i, &sel->result);
            }

            if ((__FD_ISSET(i, &sel->result)) && (ret == -EFAULT))
                ret = 0;

            restore_callbacks(sel->elt[i].socket, &sel->elt[i]);
            fput(sel->elt[i].socket->file);
            sel->elt[i].socket = NULL;
        }
    }

    /* XXX this is not an error, -EFAULT is used here as the timeout return
     * value....
     * FIXME use ETIME to have an explicit timeout. */
    if (ret == -EFAULT)
        __FD_ZERO(&sel->result);

    return ret;
}