if (!acpt_num)  EVNT__COPY_TV(&scan->mtime);
void evnt_scan_fds(unsigned int ready, size_t max_sz){  const int bad_poll_flags = (POLLERR | POLLHUP | POLLNVAL);  struct Evnt *scan = NULL;  EVNT__UPDATE_TV();    scan = q_connect;  while (scan && ready)  {    struct Evnt *scan_next = scan->next;    int done = FALSE;    ASSERT(evnt__valid(scan));        if (scan->flag_q_closed)      goto next_connect;        assert(!(SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLIN));    /* done as one so we get error code */    if (SOCKET_POLL_INDICATOR(scan->ind)->revents & (POLLOUT|bad_poll_flags))    {      int ern = 0;      socklen_t len = sizeof(int);      int ret = 0;            done = TRUE;            ret = getsockopt(evnt_fd(scan), SOL_SOCKET, SO_ERROR, &ern, &len);      if (ret == -1)        vlg_err(vlg, EXIT_FAILURE, "getsockopt(SO_ERROR): %m\n");      else if (ern)      {        errno = ern;        vlg_warn(vlg, "connect(): %m\n");        evnt__close_now(scan);      }      else      {        evnt_del(&q_connect, scan); scan->flag_q_connect = FALSE;        evnt_add(&q_none,    scan); scan->flag_q_none    = TRUE;        evnt_wait_cntl_del(scan, POLLOUT);        if (!scan->cbs->cb_func_connect(scan))          evnt__close_now(scan);      }      goto next_connect;    }    ASSERT(!done);    if (evnt_poll_direct_enabled()) break;   next_connect:    SOCKET_POLL_INDICATOR(scan->ind)->revents = 0;    if (done)      --ready;    scan = scan_next;  }  scan = q_accept;  while (scan && ready)  { /* Papers have suggested that preferring read over accept is better     * -- edge triggering needs to requeue on non failure */    struct Evnt *scan_next = scan->next;    int done = FALSE;    ASSERT(evnt__valid(scan));        if (scan->flag_q_closed)      goto next_accept;        assert(!(SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLOUT));    if (!done && (SOCKET_POLL_INDICATOR(scan->ind)->revents & bad_poll_flags))    { /* done first as it's an error with the accept fd, whereas accept       * generates new fds */      done = TRUE;      evnt__close_now(scan);      goto next_accept;    }    if (SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLIN)    {      struct sockaddr_in sa;      socklen_t len = sizeof(struct sockaddr_in);      int fd = -1;      struct Evnt *tmp = NULL;      unsigned int acpt_num = 0;            done = TRUE;      /* ignore all accept() errors -- bad_poll_flags fixes here */      /* FIXME: apache seems to assume certain errors are really bad and we       * should just kill the listen socket and wait to die. But for instance.       * we can't just kill the socket on EMFILE, as we might have hit our       * resource limit */      while ((SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLIN) &&             (fd = accept(evnt_fd(scan), (struct sockaddr *) &sa, &len)) != -1)      {        if (!(tmp = scan->cbs->cb_func_accept(scan, fd,                                              (struct sockaddr *) &sa, len)))        {          close(fd);          goto next_accept;        }              if (!tmp->flag_q_closed)        {          ++ready; /* give a read event to this new event */          tmp->flag_fully_acpt = TRUE;        }        assert(SOCKET_POLL_INDICATOR(tmp->ind)->events  == POLLIN);        assert(SOCKET_POLL_INDICATOR(tmp->ind)->revents == POLLIN);        assert(tmp == q_recv);                if (++acpt_num >= evnt__accept_limit)          break;      }            goto next_accept;    }    ASSERT(!done);    if (evnt_poll_direct_enabled()) break;       next_accept:    SOCKET_POLL_INDICATOR(scan->ind)->revents = 0;    if (done)      --ready;    scan = scan_next;  }    scan = q_recv;  while (scan && ready)  {    struct Evnt *scan_next = scan->next;    int done = FALSE;        ASSERT(evnt__valid(scan));        if (scan->flag_q_closed)      goto next_recv;        if (SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLIN)    {      done = TRUE;      if (!scan->cbs->cb_func_recv(scan))        evnt__close_now(scan);    }    if (!done && (SOCKET_POLL_INDICATOR(scan->ind)->revents & bad_poll_flags))    {      done = TRUE;      if (scan->io_r_shutdown || scan->io_w_shutdown ||          !scan->cbs->cb_func_shutdown_r(scan))        evnt__close_now(scan);    }    if (!done && evnt_poll_direct_enabled()) break;   next_recv:    if (done)      --ready;        scan = scan_next;  }  scan = q_send_recv;  while (scan && ready)  {    struct Evnt *scan_next = scan->next;    int done = FALSE;        ASSERT(evnt__valid(scan));        if (scan->flag_q_closed)      goto next_send;    if (SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLIN)    {      done = TRUE;      if (!scan->cbs->cb_func_recv(scan))      {        evnt__close_now(scan);        goto next_send;      }    }        if (SOCKET_POLL_INDICATOR(scan->ind)->revents & POLLOUT)    {      done = TRUE; /* need groups so we can do direct send here */      if (!evnt_send_add(scan, TRUE, max_sz))        evnt__close_now(scan);    }    if (!done && (SOCKET_POLL_INDICATOR(scan->ind)->revents & bad_poll_flags))    {      done = TRUE;      if (scan->io_r_shutdown || !scan->cbs->cb_func_shutdown_r(scan))        evnt__close_now(scan);    }    if (!done && evnt_poll_direct_enabled()) break;   next_send:    if (done)      --ready;    scan = scan_next;  }  scan = q_none;  while (scan && ready)  {    struct Evnt *scan_next = scan->next;    int done = FALSE;    ASSERT(evnt__valid(scan));        if (scan->flag_q_closed)      goto next_none;    if (SOCKET_POLL_INDICATOR(scan->ind)->revents)    { /* POLLIN == EOF ? */      /* FIXME: failure cb */      done = TRUE;      evnt__close_now(scan);      goto next_none;    }    else      assert(!SOCKET_POLL_INDICATOR(scan->ind)->revents);    ASSERT(!done);    if (evnt_poll_direct_enabled()) break;       next_none:    if (done)      --ready;    scan = scan_next;  }  if (q_closed)    evnt_scan_q_close();  else if (ready)    vlg_abort(vlg, "ready = %d\n", ready);}