static void *listen_thread_main (void *args) /* {{{ */
{
char buffer[4096];
+ struct pollfd *pollfds;
+ int pollfds_num;
int status;
int i;
return (NULL);
}
- while (do_shutdown == 0)
+ pollfds_num = listen_fds_num;
+ pollfds = (struct pollfd *) malloc (sizeof (*pollfds) * pollfds_num);
+ if (pollfds == NULL)
{
- int *client_sd;
- struct sockaddr_storage client_sa;
- socklen_t client_sa_size;
- pthread_t tid;
+ RRDD_LOG (LOG_ERR, "listen_thread_main: malloc failed.");
+ return (NULL);
+ }
+ memset (pollfds, 0, sizeof (*pollfds) * pollfds_num);
- client_sd = (int *) malloc (sizeof (int));
- if (client_sd == NULL)
+ while (do_shutdown == 0)
+ {
+ assert (pollfds_num == listen_fds_num);
+ for (i = 0; i < pollfds_num; i++)
{
- RRDD_LOG (LOG_ERR, "listen_thread_main: malloc failed.");
- sleep (120);
- continue;
+ pollfds[i].fd = listen_fds[i].fd;
+ pollfds[i].events = POLLIN | POLLPRI;
+ pollfds[i].revents = 0;
}
- client_sa_size = sizeof (client_sa);
- /* FIXME: Don't implement listen_fds as a list or use poll(2) here! */
- *client_sd = accept (listen_fds[0].fd,
- (struct sockaddr *) &client_sa, &client_sa_size);
- if (*client_sd < 0)
+ status = poll (pollfds, pollfds_num, /* timeout = */ -1);
+ if (status < 1)
{
- RRDD_LOG (LOG_ERR, "listen_thread_main: accept(2) failed.");
+ status = errno;
+ if (status != EINTR)
+ {
+ RRDD_LOG (LOG_ERR, "listen_thread_main: poll(2) failed.");
+ }
continue;
}
- RRDD_LOG (LOG_DEBUG, "listen_thread_main: accept(2) returned fd #%i.",
- *client_sd);
-
- status = pthread_create (&tid, /* attr = */ NULL, connection_thread_main,
- /* args = */ (void *) client_sd);
- if (status != 0)
+ for (i = 0; i < pollfds_num; i++)
{
- RRDD_LOG (LOG_ERR, "listen_thread_main: pthread_create failed.");
- close (*client_sd);
- free (client_sd);
- continue;
- }
+ int *client_sd;
+ struct sockaddr_storage client_sa;
+ socklen_t client_sa_size;
+ pthread_t tid;
+
+ if (pollfds[i].revents == 0)
+ continue;
+
+ if ((pollfds[i].revents & (POLLIN | POLLPRI)) == 0)
+ {
+ RRDD_LOG (LOG_ERR, "listen_thread_main: "
+ "poll(2) returned something unexpected for listen FD #%i.",
+ pollfds[i].fd);
+ continue;
+ }
+
+ client_sd = (int *) malloc (sizeof (int));
+ if (client_sd == NULL)
+ {
+ RRDD_LOG (LOG_ERR, "listen_thread_main: malloc failed.");
+ continue;
+ }
+
+ client_sa_size = sizeof (client_sa);
+ *client_sd = accept (pollfds[i].fd,
+ (struct sockaddr *) &client_sa, &client_sa_size);
+ if (*client_sd < 0)
+ {
+ RRDD_LOG (LOG_ERR, "listen_thread_main: accept(2) failed.");
+ continue;
+ }
+
+ RRDD_LOG (LOG_DEBUG, "listen_thread_main: accept(2) returned fd #%i.",
+ *client_sd);
+
+ status = pthread_create (&tid, /* attr = */ NULL, connection_thread_main,
+ /* args = */ (void *) client_sd);
+ if (status != 0)
+ {
+ RRDD_LOG (LOG_ERR, "listen_thread_main: pthread_create failed.");
+ close (*client_sd);
+ free (client_sd);
+ continue;
+ }
- RRDD_LOG (LOG_DEBUG, "listen_thread_main: pthread_create succeeded: "
- "tid = %lu",
- *((unsigned long *) &tid));
+ RRDD_LOG (LOG_DEBUG, "listen_thread_main: pthread_create succeeded: "
+ "tid = %lu",
+ *((unsigned long *) &tid));
+ } /* for (pollfds_num) */
} /* while (do_shutdown == 0) */
close_listen_sockets ();