about summary refs log tree commit homepage
path: root/ext/kgio/accept.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-01-27 19:43:39 -0800
committerEric Wong <normalperson@yhbt.net>2011-01-27 19:45:52 -0800
commit910f6f3df099c04fcd55bd6b20785cce69cb36ae (patch)
tree4cc051bc7155b0b655a44fa19666a8870c5ece49 /ext/kgio/accept.c
parentec91ac3d8c8d9236ba0cd01794c9c4a3ee3f7eeb (diff)
downloadkgio-910f6f3df099c04fcd55bd6b20785cce69cb36ae.tar.gz
It only supports TCP_CORK under Linux right now.

We use a very basic strategy to use TCP_CORK semantics optimally
in most TCP servers:  On corked sockets, we will uncork on recv()
if there was a previous send().  Otherwise we do not fiddle
with TCP_CORK at all.

Under Linux, we can rely on TCP_CORK being inherited in an
accept()-ed client socket so we can avoid syscalls for each
accept()-ed client if we already know the accept() socket corks.

This module does NOTHING for client TCP sockets, we only deal
with accept()-ed sockets right now.
Diffstat (limited to 'ext/kgio/accept.c')
-rw-r--r--ext/kgio/accept.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/ext/kgio/accept.c b/ext/kgio/accept.c
index 66c2712..a147fec 100644
--- a/ext/kgio/accept.c
+++ b/ext/kgio/accept.c
@@ -133,14 +133,21 @@ static VALUE acceptor(int argc, const VALUE *argv)
         rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
 }
 
+#if defined(__linux__)
+#  define post_accept kgio_nopush_accept
+#else
+#  define post_accept(a,b,c,d) for(;0;)
+#endif
+
 static VALUE
-my_accept(VALUE io, VALUE klass,
+my_accept(VALUE accept_io, VALUE klass,
           struct sockaddr *addr, socklen_t *addrlen, int nonblock)
 {
         int client;
+        VALUE client_io;
         struct accept_args a;
 
-        a.fd = my_fileno(io);
+        a.fd = my_fileno(accept_io);
         a.addr = addr;
         a.addrlen = addrlen;
 retry:
@@ -175,7 +182,9 @@ retry:
                         rb_sys_fail("accept");
                 }
         }
-        return sock_for_fd(klass, client);
+        client_io = sock_for_fd(klass, client);
+        post_accept(accept_io, client_io, a.fd, client);
+        return client_io;
 }
 
 static void in_addr_set(VALUE io, struct sockaddr_in *addr)