static int tcp_wait_for_events(tcp_context_t *tcp) { /* Wait for events. */ fdset_t *set = &tcp->set; int nfds = poll(set->pfd, set->n, TCP_SWEEP_INTERVAL * 1000); /* Mark the time of last poll call. */ time_now(&tcp->last_poll_time); bool is_throttled = (tcp->last_poll_time.tv_sec < tcp->throttle_end.tv_sec); if (!is_throttled) { /* Configuration limit, infer maximal pool size. */ rcu_read_lock(); conf_val_t *val = &conf()->cache.srv_max_tcp_clients; unsigned max_per_set = MAX(conf_int(val) / conf_tcp_threads(conf()), 1); rcu_read_unlock(); /* Subtract master sockets check limits. */ is_throttled = (set->n - tcp->client_threshold) >= max_per_set; } /* Process events. */ unsigned i = 0; while (nfds > 0 && i < set->n) { bool should_close = false; int fd = set->pfd[i].fd; if (set->pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { should_close = (i >= tcp->client_threshold); --nfds; } else if (set->pfd[i].revents & (POLLIN)) { /* Master sockets */ if (i < tcp->client_threshold) { if (!is_throttled && tcp_event_accept(tcp, i) == KNOT_EBUSY) { time_now(&tcp->throttle_end); tcp->throttle_end.tv_sec += tcp_throttle(); } /* Client sockets */ } else { if (tcp_event_serve(tcp, i) != KNOT_EOK) { should_close = true; } } --nfds; } /* Evaluate */ if (should_close) { fdset_remove(set, i); close(fd); } else { ++i; } } return nfds; }
static int tcp_wait_for_events(tcp_context_t *tcp) { /* Wait for events. */ fdset_t *set = &tcp->set; int nfds = poll(set->pfd, set->n, TCP_SWEEP_INTERVAL * 1000); /* Mark the time of last poll call. */ time_now(&tcp->last_poll_time); /* Process events. */ unsigned i = 0; while (nfds > 0 && i < set->n) { /* Terminate faulty connections. */ int fd = set->pfd[i].fd; /* Active sockets. */ if (set->pfd[i].revents & POLLIN) { --nfds; /* One less active event. */ /* Indexes <0, client_threshold) are master sockets. */ if (i < tcp->client_threshold) { /* Faulty master sockets shall be sorted later. */ (void) tcp_event_accept(tcp, i); } else { if (tcp_event_serve(tcp, i) != KNOT_EOK) { fdset_remove(set, i); close(fd); continue; /* Stay on the same index. */ } } } if (set->pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { --nfds; /* One less active event. */ fdset_remove(set, i); close(fd); continue; /* Stay on the same index. */ } /* Next socket. */ ++i; } return nfds; }