From d24aa7d6ceac4914906ce76aa729fd5c7011eb3d Mon Sep 17 00:00:00 2001 From: LAN-TW Date: Tue, 14 Jan 2014 16:22:25 +0800 Subject: =?UTF-8?q?HW4:=20=E5=9F=BA=E6=9C=AC=E7=9A=84=20poll=20=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hw4/chttpd/chttpd-server.c | 53 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/hw4/chttpd/chttpd-server.c b/hw4/chttpd/chttpd-server.c index f9c6f33..aab0839 100644 --- a/hw4/chttpd/chttpd-server.c +++ b/hw4/chttpd/chttpd-server.c @@ -240,6 +240,14 @@ static void server_notify_setter (int signo) { static void dummy_handler (int signo) { } +static char* get_errmsg (int errnum, char* buf, size_t buflen) { + if (strerror_r (errnum, buf, buflen) != 0) { + snprintf (buf, buflen, "Unknown error %d", errnum); + } + return buf; +} + +#define ERRLEN 256 static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { chttpd_server_notify = 1; chttpd_server_notify_data.attr_close = true; @@ -256,6 +264,9 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { sigaddset (&crit_mask, SIGUSR2); struct pollfd* pfds = NULL; + nfds_t nfds = 0; + + char errmsg[ERRLEN]; while (lbs_list_meta_get_len (slist) > 0) { pthread_sigmask (SIG_BLOCK, &crit_mask, NULL); @@ -305,6 +316,7 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { /* Rebuild poll fd list */ if (slist->len > 0) { pfds = xrealloc (pfds, sizeof (struct pollfd) * slist->len); + nfds = slist->len; unsigned c = 0; for (iter = slist->first; iter != NULL; iter = iter->next, c++) { ChttpdServer* server = iter->data; @@ -317,6 +329,7 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { } else { free (pfds); pfds = NULL; + nfds = 0; } @@ -379,11 +392,49 @@ static void chttpd_main_loop (ChttpdLog* hlog, LbsListMeta* slist) { } pthread_sigmask (SIG_UNBLOCK, &crit_mask, NULL); - /* */ + + /* Poll for new request */ + if (pfds == NULL) { + continue; + } + + int pollrv = poll (pfds, nfds, -1); + if (pollrv < 0) { + chttpd_log_write (hlog, "[main] poll: %s", + get_errmsg (errno, errmsg, ERRLEN)); + continue; + } + + LbsList* iter = slist->first; + for (int i = 0; i < nfds; i++, iter = iter->next) { + if (pfds[i].revents & POLLIN || pfds[i].revents & POLLPRI) { + pfds[i].revents = 0; /* Reset revents */ + + ChttpdServer* server = iter->data; + int connfd = accept (server->sockfd, NULL, NULL); + if (connfd < 0) { + chttpd_log_write (hlog, "[main] accept: %s", + get_errmsg (errno, errmsg, ERRLEN)); + continue; + } + + unsigned long long count; + pthread_rwlock_wrlock (&chttpd_server_count_lock); + count = chttpd_server_count++; + pthread_rwlock_unlock (&chttpd_server_count_lock); + + char* peername = lbs_posix_socket_peername (connfd); + chttpd_log_write (hlog, "[main] connection %llu from %s " + "accepted", count, peername); + free (peername); + + } + } } free (pfds); } +#undef ERRLEN void chttpd_server_ctor (void* server_generic, ChttpdLog* hlog, bool is_admin) { ChttpdServer* server = server_generic; -- cgit v1.2.3