about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2010-09-27 00:57:14 +0000
committerEric Wong <e@yhbt.net>2010-09-27 00:57:14 +0000
commitf81cb3c05a0eb46ec61ceb295b51ead16e6a0da4 (patch)
tree5a3708279dbccbf12da803300cffe5f9d219da36
parent87cf3ce6185b9138032a5af53cecae98f8c93564 (diff)
downloadkgio-f81cb3c05a0eb46ec61ceb295b51ead16e6a0da4.tar.gz
This saves us a relatively expensive fcntl() system call.
-rw-r--r--ext/kgio/kgio_ext.c30
-rw-r--r--ext/kgio/missing/accept4.h15
2 files changed, 29 insertions, 16 deletions
diff --git a/ext/kgio/kgio_ext.c b/ext/kgio/kgio_ext.c
index 977273d..7818425 100644
--- a/ext/kgio/kgio_ext.c
+++ b/ext/kgio/kgio_ext.c
@@ -26,9 +26,9 @@
  * notice.
  */
 #  define USE_MSG_DONTWAIT
-static int accept4_flags = SOCK_CLOEXEC;
+static int accept4_flags = A4_SOCK_CLOEXEC;
 #else /* ! linux */
-static int accept4_flags = SOCK_CLOEXEC | SOCK_NONBLOCK;
+static int accept4_flags = A4_SOCK_CLOEXEC | A4_SOCK_NONBLOCK;
 #endif /* ! linux */
 
 static VALUE cSocket;
@@ -411,22 +411,24 @@ static VALUE tcp_accept(VALUE io)
 
 static VALUE get_cloexec(VALUE mod)
 {
-        return (accept4_flags & SOCK_CLOEXEC) == SOCK_CLOEXEC ? Qtrue : Qfalse;
+        return (accept4_flags & A4_SOCK_CLOEXEC) ==
+            A4_SOCK_CLOEXEC ? Qtrue : Qfalse;
 }
 
 static VALUE get_nonblock(VALUE mod)
 {
-        return (accept4_flags & SOCK_NONBLOCK)==SOCK_NONBLOCK ? Qtrue : Qfalse;
+        return (accept4_flags & A4_SOCK_NONBLOCK) ==
+            A4_SOCK_NONBLOCK ? Qtrue : Qfalse;
 }
 
 static VALUE set_cloexec(VALUE mod, VALUE boolean)
 {
         switch (TYPE(boolean)) {
         case T_TRUE:
-                accept4_flags |= SOCK_CLOEXEC;
+                accept4_flags |= A4_SOCK_CLOEXEC;
                 return boolean;
         case T_FALSE:
-                accept4_flags &= ~SOCK_CLOEXEC;
+                accept4_flags &= ~A4_SOCK_CLOEXEC;
                 return boolean;
         }
         rb_raise(rb_eTypeError, "not true or false");
@@ -437,10 +439,10 @@ static VALUE set_nonblock(VALUE mod, VALUE boolean)
 {
         switch (TYPE(boolean)) {
         case T_TRUE:
-                accept4_flags |= SOCK_NONBLOCK;
+                accept4_flags |= A4_SOCK_NONBLOCK;
                 return boolean;
         case T_FALSE:
-                accept4_flags &= ~SOCK_NONBLOCK;
+                accept4_flags &= ~A4_SOCK_NONBLOCK;
                 return boolean;
         }
         rb_raise(rb_eTypeError, "not true or false");
@@ -455,10 +457,16 @@ static void close_fail(int fd, const char *msg)
         rb_sys_fail(msg);
 }
 
+#ifdef SOCK_NONBLOCK
+#  define MY_SOCK_STREAM (SOCK_STREAM|SOCK_NONBLOCK)
+#else
+#  define MY_SOCK_STREAM SOCK_STREAM
+#endif /* ! SOCK_NONBLOCK */
+
 static VALUE
 my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
 {
-        int fd = socket(domain, SOCK_STREAM, 0);
+        int fd = socket(domain, MY_SOCK_STREAM, 0);
 
         if (fd == -1) {
                 switch (errno) {
@@ -469,14 +477,16 @@ my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
 #endif /* ENOBUFS */
                         errno = 0;
                         rb_gc();
-                        fd = socket(domain, SOCK_STREAM, 0);
+                        fd = socket(domain, MY_SOCK_STREAM, 0);
                 }
                 if (fd == -1)
                         rb_sys_fail("socket");
         }
 
+#ifndef SOCK_NONBLOCK
         if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
                 close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
+#endif /* SOCK_NONBLOCK */
 
         if (connect(fd, addr, addrlen) == -1) {
                 if (errno == EINPROGRESS) {
diff --git a/ext/kgio/missing/accept4.h b/ext/kgio/missing/accept4.h
index cd8be79..482f3ad 100644
--- a/ext/kgio/missing/accept4.h
+++ b/ext/kgio/missing/accept4.h
@@ -6,12 +6,15 @@
 #  include <sys/socket.h>
 #  ifndef SOCK_CLOEXEC
 #    if (FD_CLOEXEC == O_NONBLOCK)
-#      define SOCK_CLOEXEC 1
-#      define SOCK_NONBLOCK 2
+#      define A4_SOCK_CLOEXEC 1
+#      define A4_SOCK_NONBLOCK 2
 #    else
-#      define SOCK_CLOEXEC FD_CLOEXEC
-#      define SOCK_NONBLOCK O_NONBLOCK
+#      define A4_SOCK_CLOEXEC FD_CLOEXEC
+#      define A4_SOCK_NONBLOCK O_NONBLOCK
 #    endif
+#  else
+#    define A4_SOCK_CLOEXEC SOCK_CLOEXEC
+#    define A4_SOCK_NONBLOCK SOCK_NONBLOCK
 #  endif
 
 /* accept4() is currently a Linux-only goodie */
@@ -21,7 +24,7 @@ accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
         int fd = accept(sockfd, addr, addrlen);
 
         if (fd >= 0) {
-                if ((flags & SOCK_CLOEXEC) == SOCK_CLOEXEC)
+                if ((flags & A4_SOCK_CLOEXEC) == A4_SOCK_CLOEXEC)
                         (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
 
                 /*
@@ -30,7 +33,7 @@ accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
                  * Linux, so fcntl() is completely unnecessary
                  * in most cases...
                  */
-                if ((flags & SOCK_NONBLOCK) == SOCK_NONBLOCK) {
+                if ((flags & A4_SOCK_NONBLOCK) == A4_SOCK_NONBLOCK) {
                         int fl = fcntl(fd, F_GETFL);
 
                         if ((fl & O_NONBLOCK) == 0)