static int UNSAFE_accept_many_server(struct pollfd *pfd, int max, struct sockaddr *sa, socklen_t *saSize, GError **err) { int nbEvents = poll(pfd, max, 2000); /* timeout or error */ if (nbEvents == 0) return -1; if (nbEvents < 0) { if (errno != EINTR && errno != EAGAIN) GSETERROR(err,"poll error : %s", strerror(errno)); return -1; } /* events! */ for (int i=0; i<max ;i++) { if (!pfd[i].revents) continue; if (pfd[i].revents & POLLIN) { int clt = accept_nonblock(pfd[i].fd, sa, saSize); if (clt >= 0) return clt; if (errno != EAGAIN && errno != EINTR) GSETERROR(err,"accept error : %s", strerror(errno)); return -1; } } return -1; }
static struct network_client_s * _endpoint_manage_event(struct network_server_s *srv, struct endpoint_s *e) { int fd; struct sockaddr_storage ss; socklen_t ss_len; retry: memset(&ss, 0, sizeof(ss)); ss_len = sizeof(ss); fd = accept_nonblock(e->fd, (struct sockaddr*)&ss, &ss_len); if (0 > fd) { if (errno == EINTR) goto retry; if (errno != EAGAIN && errno != EWOULDBLOCK) GRID_WARN("fd=%d ACCEPT error (%d %s)", e->fd, errno, strerror(errno)); return NULL; } switch (e->flags) { case NETSERVER_THROUGHPUT: sock_set_cork(fd, TRUE); break; case NETSERVER_LATENCY: sock_set_linger_default(fd); sock_set_nodelay(fd, TRUE); sock_set_tcpquickack(fd, TRUE); break; default: break; } struct network_client_s *clt = SLICE_NEW0(struct network_client_s); if (NULL == clt) { metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } switch (_cnx_notify_accept(srv)) { case EXCESS_SOFT: clt->current_error = NEWERROR(CODE_UNAVAILABLE, "Server overloaded."); case EXCESS_NONE: break; case EXCESS_HARD: metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } clt->main_stats = srv->stats; clt->server = srv; clt->fd = fd; grid_sockaddr_to_string((struct sockaddr*)&ss, clt->peer_name, sizeof(clt->peer_name)); _client_sock_name(fd, clt->local_name, sizeof(clt->local_name)); clt->time.cnx = network_server_bogonow(srv); clt->events = CLT_READ; clt->input.first = clt->input.last = NULL; clt->output.first = clt->output.last = NULL; if (e->factory_hook) e->factory_hook(e->factory_udata, clt); return clt; }