diff options
author | LAN-TW <lantw44@gmail.com> | 2014-01-14 16:22:25 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2014-01-14 16:22:25 +0800 |
commit | d24aa7d6ceac4914906ce76aa729fd5c7011eb3d (patch) | |
tree | 264cb71cc1f82c2626b884726867963613665f57 | |
parent | 7eca0c4b5f280c7fcacb59460136389ee8ac57ef (diff) | |
download | sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar.gz sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar.bz2 sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar.lz sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar.xz sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.tar.zst sp2013-d24aa7d6ceac4914906ce76aa729fd5c7011eb3d.zip |
HW4: 基本的 poll 操作
-rw-r--r-- | hw4/chttpd/chttpd-server.c | 53 |
1 files changed, 52 insertions, 1 deletions
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; |