From 7e7b80716d75630bb7be51da63c7eafe32cc3b2e Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 22 Jun 2008 13:28:52 +0200 Subject: [PATCH] src/rrdd.c: Implement listening on multiple sockets. --- src/rrdd.c | 102 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/src/rrdd.c b/src/rrdd.c index 6ce6b10..7cd2431 100644 --- a/src/rrdd.c +++ b/src/rrdd.c @@ -614,6 +614,8 @@ static int close_listen_sockets (void) /* {{{ */ static void *listen_thread_main (void *args) /* {{{ */ { char buffer[4096]; + struct pollfd *pollfds; + int pollfds_num; int status; int i; @@ -631,47 +633,87 @@ static void *listen_thread_main (void *args) /* {{{ */ 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 (); -- 2.11.0