summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Liu <simohayha.bobo@gmail.com>2012-07-21 14:33:33 +0800
committerdormando <dormando@rydia.net>2013-12-19 19:22:54 -0800
commit6d02111b3eda21e3e94caab2f645232216c1f59b (patch)
treedcbe4356964d9b2ac9558e7d8c1059443afc180f
parent145bcfd09a3fd8ba20543dd497728c29fb613e38 (diff)
downloadmemcached-6d02111b3eda21e3e94caab2f645232216c1f59b.tar.gz
Add linux accept4() support.
-rw-r--r--configure.ac1
-rw-r--r--memcached.c41
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) {