From 6d02111b3eda21e3e94caab2f645232216c1f59b Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Sat, 21 Jul 2012 14:33:33 +0800 Subject: Add linux accept4() support. --- configure.ac | 1 + memcached.c | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index f2639d6..7f22f21 100644 --- a/configure.ac +++ b/configure.ac @@ -476,6 +476,7 @@ AC_CHECK_FUNCS(getpagesizes) AC_CHECK_FUNCS(memcntl) AC_CHECK_FUNCS(sigignore) AC_CHECK_FUNCS(clock_gettime) +AC_CHECK_FUNCS([accept4], [AC_DEFINE(HAVE_ACCEPT4, 1, [Define to 1 if support accept4])]) AC_DEFUN([AC_C_ALIGNMENT], [AC_CACHE_CHECK(for alignment, ac_cv_c_alignment, diff --git a/memcached.c b/memcached.c index 9ec1597..eba0742 100644 --- a/memcached.c +++ b/memcached.c @@ -3792,12 +3792,15 @@ static enum transmit_result transmit(conn *c) { static void drive_machine(conn *c) { bool stop = false; - int sfd, flags = 1; + int sfd; socklen_t addrlen; struct sockaddr_storage addr; int nreqs = settings.reqs_per_event; int res; const char *str; +#if (HAVE_ACCEPT4) + static int use_accept4 = 1; +#endif assert(c != NULL); @@ -3806,7 +3809,26 @@ static void drive_machine(conn *c) { switch(c->state) { case conn_listening: addrlen = sizeof(addr); - if ((sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen)) == -1) { +#if (HAVE_ACCEPT4) + if (use_accept4) { + sfd = accept4(c->sfd, (struct sockaddr *)&addr, &addrlen, SOCK_NONBLOCK); + } else { + sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen); + } +#else + sfd = accept(c->sfd, (struct sockaddr *)&addr, &addrlen); +#endif + if (sfd == -1) { +#if (HAVE_ACCEPT4) + + if (use_accept4 && errno == ENOSYS) { + use_accept4 = 0; + continue; + } + perror(use_accept4 ? "accept4()" : "accept()"); +#else + perror("accept()"); +#endif if (errno == EAGAIN || errno == EWOULDBLOCK) { /* these are transient, so don't log anything */ stop = true; @@ -3821,12 +3843,17 @@ static void drive_machine(conn *c) { } break; } - if ((flags = fcntl(sfd, F_GETFL, 0)) < 0 || - fcntl(sfd, F_SETFL, flags | O_NONBLOCK) < 0) { - perror("setting O_NONBLOCK"); - close(sfd); - break; +#if (HAVE_ACCEPT4) + if (!use_accept4) { +#endif + if (fcntl(sfd, F_SETFL, fcntl(sfd, F_GETFL) | O_NONBLOCK) < 0) { + perror("setting O_NONBLOCK"); + close(sfd); + break; + } +#if (HAVE_ACCEPT4) } +#endif if (settings.maxconns_fast && stats.curr_conns + stats.reserved_fds >= settings.maxconns - 1) { -- cgit v1.2.1