Пример #1
0
/*
 * comm_setselect
 *
 * This is a needed exported function which will be called to register
 * and deregister interest in a pending IO state for a given FD.
 */
void
comm_setselect(int fd, fdlist_t list, unsigned int type, PF *handler,
               void *client_data, time_t timeout)
{
  fde_t *F = &fd_table[fd];

  assert(fd >= 0);
  assert(F->flags.open);

  if (type & COMM_SELECT_READ)
  {
    F->read_handler = handler;
    F->read_data = client_data;
    poll_update_pollfds(fd, POLLIN, handler);
  }
  if (type & COMM_SELECT_WRITE)
  {
    F->write_handler = handler;
    F->write_data = client_data;
    poll_update_pollfds(fd, POLLOUT, handler);
  }

  if (timeout)
    F->timeout = CurrentTime + (timeout / 1000);
}
Пример #2
0
/* void comm_select_fdlist(unsigned long delay)
 * Input: The maximum time to delay.
 * Output: None
 * 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 of squid (like most of this
 * new IO code). This routine handles the stuff we've hidden in
 * comm_setselect and fd_table[] and calls callbacks for IO ready
 * events.
 */
void
comm_select(unsigned long delay)
{
  int num, fd, ci, revents;
  PF *hdl;
  fde_t *F;
  
  /* XXX kill that +1 later ! -- adrian */
  while ((num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay)) < 0
         && ignoreErrno(errno))
    ;

  set_time();
 
  if (num == 0)
    return;

  /* XXX we *could* optimise by falling out after doing num fds ...
   * Currently it'd be hard to do, because pollfd_list can be changed
   * within this loop (by I/O handlers) --adx
   */
  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 = &fd_table[fd];

    if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
    {
      hdl = F->read_handler;
      F->read_handler = NULL;
      poll_update_pollfds(fd, POLLRDNORM, NULL);
      if (hdl)
       hdl(fd, F->read_data);
    }
    if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
    {
      hdl = F->write_handler;
      F->write_handler = NULL;
      poll_update_pollfds(fd, POLLWRNORM, NULL);
      if (hdl)
        hdl(fd, F->write_data);
    }
  }
}
Пример #3
0
/*
 * comm_setselect
 *
 * This is a needed exported function which will be called to register
 * and deregister interest in a pending IO state for a given FD.
 */
void
comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
	       void *client_data)
{
	fde_t *F = &fd_table[fd];
	s_assert(fd >= 0);
	s_assert(F->flags.open);

	if(type & COMM_SELECT_READ)
	{
		F->read_handler = handler;
		F->read_data = client_data;
		poll_update_pollfds(fd, POLLRDNORM, handler);
	}
	if(type & COMM_SELECT_WRITE)
	{
		F->write_handler = handler;
		F->write_data = client_data;
		poll_update_pollfds(fd, POLLWRNORM, handler);
	}
}
Пример #4
0
/* int comm_select(unsigned 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 of squid (like most of this
 * new IO code). This routine handles the stuff we've hidden in
 * comm_setselect and fd_table[] and calls callbacks for IO ready
 * events.
 */
int comm_select(unsigned long delay)
{
    int num = 0;
    int revents = 0;
    int sig;
    int fd;
    int ci;
    PF *hdl;
    fde_t *F;
    struct siginfo si;
    struct timespec timeout;
    timeout.tv_sec = 0;
    timeout.tv_nsec = 1000000 * delay;
    for (;;)
    {
        if (!sigio_is_screwed)
        {
            if ((sig = sigtimedwait(&our_sigset, &si, &timeout)) > 0)
            {
                if (sig == SIGIO)
                {
                    ilog(L_WARN, "Kernel RT Signal queue overflowed.  Is /proc/sys/kernel/rtsig-max too small?");
                    sigio_is_screwed = 1;
                    break;
                }
                fd = si.si_fd;
                pollfd_list.pollfds[fd].revents |= si.si_band;
                revents = pollfd_list.pollfds[fd].revents;
                num++;
                F = &fd_table[fd];
                set_time();
                if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
                {
                    callbacks_called++;
                    hdl = F->read_handler;
                    F->read_handler = NULL;
                    poll_update_pollfds(fd, POLLIN, NULL);
                    if (hdl)
                        hdl(fd, F->read_data);
                }
                if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
                {
                    callbacks_called++;
                    hdl = F->write_handler;
                    F->write_handler = NULL;
                    poll_update_pollfds(fd, POLLOUT, NULL);
                    if (hdl)
                        hdl(fd, F->write_data);
                }
            } else
                break;

        } else
            break;
    }
    
    if (!sigio_is_screwed)      /* We don't need to proceed */
    {
        set_time();
        return 0;
    }
    for (;;)
    {
        if (sigio_is_screwed)
        {
            signal(sigio_signal, SIG_IGN);
            signal(sigio_signal, SIG_DFL);
            sigio_is_screwed = 0;
        }
        num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0);
        if (num >= 0)
            break;
        if (ignoreErrno(errno))
            continue;
        /* error! */
        set_time();
        return -1;
        /* NOTREACHED */
    }

    /* update current time again, eww.. */
    set_time();

    if (num == 0)
        return 0;
    /* 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 = &fd_table[fd];
        if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
        {
            callbacks_called++;
            hdl = F->read_handler;
            F->read_handler = NULL;
            poll_update_pollfds(fd, POLLIN, NULL);
            if (hdl)
                hdl(fd, F->read_data);
        }
        if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
        {
            callbacks_called++;
            hdl = F->write_handler;
            F->write_handler = NULL;
            poll_update_pollfds(fd, POLLOUT, NULL);
            if (hdl)
                hdl(fd, F->write_data);
        }
    }
    mask_our_signal(sigio_signal);
    return 0;
}
Пример #5
0
/* void comm_select(unsigned long delay)
 * Input: The maximum time to delay.
 * Output: None
 * 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
 * comm_setselect and fd_table[] and calls callbacks for IO ready
 * events.
 */
void
comm_select(unsigned long delay)
{
  int revents = 0, sig, fd;
  PF *hdl;
  fde_t *F;
  struct siginfo si;
  struct timespec timeout;

  timeout.tv_sec = 0;
  timeout.tv_nsec = 1000000 * delay;
  sig = sigtimedwait(&our_sigset, &si, &timeout);
  set_time();
  if (sig != SIGIO)
  {
    if (sig > 0)
    {
      fd = si.si_fd;
      pollfd_list.pollfds[fd].revents |= si.si_band;
      revents = pollfd_list.pollfds[fd].revents;
      F = &fd_table[fd];
      if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
      {
        hdl = F->read_handler;
        F->read_handler = NULL;
        poll_update_pollfds(fd, POLLIN, NULL);
        if (hdl)
          hdl(fd, F->read_data);
      }
      if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
      {
        hdl = F->write_handler;
        F->write_handler = NULL;
        poll_update_pollfds(fd, POLLOUT, NULL);
        if (hdl)
          hdl(fd, F->write_data);
      }
    }
    return;
  }

  /* RT signal queue overflowed.. */

  if (CurrentTime - last_rtsigqo_warning >= 30)
  {
    ilog(L_WARN, "Kernel RT Signal queue overflowed.  "
                 "Is /proc/sys/kernel/rtsig-max too small?");
    last_rtsigqo_warning = CurrentTime;
  }

  signal(SIGIO_SIGNAL, SIG_IGN);
  signal(SIGIO_SIGNAL, SIG_DFL);

  /* ..try polling instead */
  {
    int num, ci;

    while ((num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0)) < 0
           && ignoreErrno(errno))
      ;

    /* update current time again, eww.. */
    set_time();

    if (num > 0)
    {
      /* 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 = &fd_table[fd];
        if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
        {
          hdl = F->read_handler;
          F->read_handler = NULL;
          poll_update_pollfds(fd, POLLIN, NULL);
          if (hdl)
            hdl(fd, F->read_data);
        }
        if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
        {
          hdl = F->write_handler;
          F->write_handler = NULL;
          poll_update_pollfds(fd, POLLOUT, NULL);
          if (hdl)
            hdl(fd, F->write_data);
        }
      }
    }
  }

  mask_our_signal(SIGIO_SIGNAL);
}
Пример #6
0
/* int comm_select_fdlist(unsigned 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
 * comm_setselect and fd_table[] and calls callbacks for IO ready
 * events.
 */
int
comm_select(unsigned long delay)
{
	int num;
	int fd;
	int ci;
	unsigned long ndelay;
	PF *hdl;

	if(last_count > 0)
	{
		empty_count = 0;
		ndelay = 0;
	}
	else {
		ndelay = ++empty_count * 15000 ;
		if(ndelay > delay * 1000)
			ndelay = delay * 1000;	
	}
	
	for (;;)
	{
		/* XXX kill that +1 later ! -- adrian */
		if(ndelay > 0)
			irc_sleep(ndelay); 
		last_count = num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, 0);
		if(num >= 0)
			break;
		if(ignoreErrno(errno))
			continue;
		/* error! */
		set_time();
		return -1;
		/* NOTREACHED */
	}

	/* update current time again, eww.. */
	set_time();

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