Exemple #1
0
static void
rb_read_timerfd(rb_fde_t *F, void *data)
{
	struct ev_entry *event = (struct ev_entry *)data;
	int retlen;
	uint64_t count;

	if(event == NULL)
	{
		rb_close(F);
		return;
	}

	retlen = rb_read(F, &count, sizeof(count));

	if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
	{
		rb_close(F);
		rb_lib_log("rb_read_timerfd: timerfd[%s] closed on error: %s", event->name,
			   strerror(errno));
		return;
	}
	rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event);
	rb_run_event(event);
}
Exemple #2
0
int
rb_select_ports(long delay)
{
	int i, fd;
	unsigned int nget = 1;
	struct timespec poll_time;
	struct timespec *p = NULL;
	struct ev_entry *ev;

	if(delay >= 0)
	{
		poll_time.tv_sec = delay / 1000;
		poll_time.tv_nsec = (delay % 1000) * 1000000;
		p = &poll_time;
	}


	i = port_getn(pe, pelst, pemax, &nget, p);
	rb_set_time();

	if(i == -1)
		return RB_OK;

	for(i = 0; (unsigned)i < nget; i++)
	{
		if(pelst[i].portev_source == PORT_SOURCE_FD)
		{
			fd = pelst[i].portev_object;
			PF *hdl = NULL;
			rb_fde_t *F = pelst[i].portev_user;
			if((pelst[i].portev_events & (POLLIN | POLLHUP | POLLERR)) && (hdl = F->read_handler))
			{
				F->read_handler = NULL;
				hdl(F, F->read_data);
			}
			if((pelst[i].portev_events & (POLLOUT | POLLHUP | POLLERR)) && (hdl = F->write_handler))
			{
				F->write_handler = NULL;
				hdl(F, F->write_data);
			}
		} else if(pelst[i].portev_source == PORT_SOURCE_TIMER)
		{
			ev = (struct ev_entry *)pelst[i].portev_user;
			rb_run_event(ev);
		}
	}
	return RB_OK;
}
Exemple #3
0
static void
signalfd_handler(rb_fde_t *F, void *data)
{
	static struct our_signalfd_siginfo fdsig[SIGFDIOV_COUNT];
	static struct iovec iov[SIGFDIOV_COUNT];
	struct ev_entry *ev;
	int ret, x;

	for(x = 0; x < SIGFDIOV_COUNT; x++)
	{
		iov[x].iov_base = &fdsig[x];
		iov[x].iov_len = sizeof(struct our_signalfd_siginfo);
	}

	while(1)
	{
		ret = readv(rb_get_fd(F), iov, SIGFDIOV_COUNT);

		if(ret == 0 || (ret < 0 && !rb_ignore_errno(errno)))
		{
			rb_close(F);
			rb_epoll_init_event();
			return;
		}

		if(ret < 0)
		{
			rb_setselect(F, RB_SELECT_READ, signalfd_handler, NULL);
			return;
		}
		for(x = 0; x < ret / (int)sizeof(struct our_signalfd_siginfo); x++)
		{
#if __WORDSIZE == 32 && defined(__sparc__)
			uint32_t *q = (uint32_t *)&fdsig[x].svptr;
			ev = (struct ev_entry *)q[0];
#else
			ev = (struct ev_entry *)(uintptr_t)(fdsig[x].svptr);

#endif
			if(ev == NULL)
				continue;
			rb_run_event(ev);
		}
	}
}
Exemple #4
0
int
rb_select_kqueue(long delay)
{
	int num, i;
	struct timespec poll_time;
	struct timespec *pt;
	rb_fde_t *F;


	if(delay < 0)
	{
		pt = NULL;
	}
	else
	{
		pt = &poll_time;
		poll_time.tv_sec = delay / 1000;
		poll_time.tv_nsec = (delay % 1000) * 1000000;
	}

	for(;;)
	{
		num = kevent(kq, kqlst, kqoff, kqout, kqmax, pt);
		kqoff = 0;

		if(num >= 0)
			break;

		if(rb_ignore_errno(errno))
			break;

		rb_set_time();

		return RB_ERROR;

		/* NOTREACHED */
	}

	rb_set_time();

	if(num == 0)
		return RB_OK;	/* No error.. */

	for(i = 0; i < num; i++)
	{
		PF *hdl = NULL;

		if(kqout[i].flags & EV_ERROR)
		{
			errno = kqout[i].data;
			/* XXX error == bad! -- adrian */
			continue;	/* XXX! */
		}

		switch (kqout[i].filter)
		{

		case EVFILT_READ:
			F = kqout[i].udata;
			if((hdl = F->read_handler) != NULL)
			{
				F->read_handler = NULL;
				hdl(F, F->read_data);
			}

			break;

		case EVFILT_WRITE:
			F = kqout[i].udata;
			if((hdl = F->write_handler) != NULL)
			{
				F->write_handler = NULL;
				hdl(F, F->write_data);
			}
			break;
#if defined(EVFILT_TIMER)
		case EVFILT_TIMER:
			rb_run_event(kqout[i].udata);
			break;
#endif
		default:
			/* Bad! -- adrian */
			break;
		}
	}
	return RB_OK;
}
Exemple #5
0
/* int rb_select(long delay)
 * Input: The maximum time to delay.
 * Output: Returns -1 on error, 0 on success.
 * Side-effects: Deregisters future interest in IO and calls the handlers
 *               if an event occurs for an FD.
 * Comments: Check all connections for new connections and input data
 * that is to be processed. Also check for connections with data queued
 * and whether we can write it out.
 * Called to do the new-style IO, courtesy of squid (like most of this
 * new IO code). This routine handles the stuff we've hidden in
 * rb_setselect and fd_table[] and calls callbacks for IO ready
 * events.
 */
int
rb_select_sigio(long delay)
{
    int num = 0;
    int revents = 0;
    int sig;
    int fd;
    int ci;
    PF *hdl;
    rb_fde_t *F;
    void *data;
    siginfo_t si;

    struct timespec timeout;
    if(rb_sigio_supports_event() || delay >= 0) {
        timeout.tv_sec = (delay / 1000);
        timeout.tv_nsec = (delay % 1000) * 1000000;
    }

    for(;;) {
        if(!sigio_is_screwed) {
            if(can_do_event || delay < 0) {
                sig = sigwaitinfo(&our_sigset, &si);
            } else
                sig = sigtimedwait(&our_sigset, &si, &timeout);

            if(sig > 0) {

                if(sig == SIGIO) {
                    rb_lib_log
                    ("Kernel RT Signal queue overflowed.  Is ulimit -i too small(or perhaps /proc/sys/kernel/rtsig-max on old kernels)");
                    sigio_is_screwed = 1;
                    break;
                }
#ifdef SIGIO_SCHED_EVENT
                if(sig == RTSIGTIM && can_do_event) {
                    struct ev_entry *ev = (struct ev_entry *)si.si_ptr;
                    if(ev == NULL)
                        continue;
                    rb_run_event(ev);
                    continue;
                }
#endif
                fd = si.si_fd;
                pollfd_list.pollfds[fd].revents |= si.si_band;
                revents = pollfd_list.pollfds[fd].revents;
                num++;
                F = rb_find_fd(fd);
                if(F == NULL)
                    continue;

                if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) {
                    hdl = F->read_handler;
                    data = F->read_data;
                    F->read_handler = NULL;
                    F->read_data = NULL;
                    if(hdl)
                        hdl(F, data);
                }

                if(revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) {
                    hdl = F->write_handler;
                    data = F->write_data;
                    F->write_handler = NULL;
                    F->write_data = NULL;
                    if(hdl)
                        hdl(F, data);
                }
            } else
                break;

        } else
            break;
    }

    if(!sigio_is_screwed) {	/* We don't need to proceed */
        rb_set_time();
        return 0;
    }

    signal(RTSIGIO, SIG_IGN);
    signal(RTSIGIO, SIG_DFL);
    sigio_is_screwed = 0;


    num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
    rb_set_time();
    if(num < 0) {
        if(!rb_ignore_errno(errno))
            return RB_OK;
        else
            return RB_ERROR;
    }
    if(num == 0)
        return RB_OK;

    /* XXX we *could* optimise by falling out after doing num fds ... */
    for(ci = 0; ci < pollfd_list.maxindex + 1; ci++) {
        if(((revents = pollfd_list.pollfds[ci].revents) == 0)
                || (pollfd_list.pollfds[ci].fd) == -1)
            continue;
        fd = pollfd_list.pollfds[ci].fd;
        F = rb_find_fd(fd);
        if(F == NULL)
            continue;
        if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) {
            hdl = F->read_handler;
            data = F->read_data;
            F->read_handler = NULL;
            F->read_data = NULL;
            if(hdl)
                hdl(F, data);
        }

        if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))) {
            hdl = F->write_handler;
            data = F->write_data;
            F->write_handler = NULL;
            F->write_data = NULL;
            if(hdl)
                hdl(F, data);
        }
        if(F->read_handler == NULL)
            rb_setselect_sigio(F, RB_SELECT_READ, NULL, NULL);
        if(F->write_handler == NULL)
            rb_setselect_sigio(F, RB_SELECT_WRITE, NULL, NULL);

    }

    return 0;
}