about summary refs log tree commit homepage
path: root/ext/kgio/kgio_ext.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2012-12-27 01:16:56 +0000
committerEric Wong <normalperson@yhbt.net>2012-12-27 01:23:34 +0000
commitf61cef65b8a8816160c622324b4f1aad55034e4a (patch)
treed5c5b285acb51b12bf407e03f304ab602c283a3d /ext/kgio/kgio_ext.c
parent7a3fc55424338ad458cc719d4cb3c4e28802d5cb (diff)
downloadkgio-f61cef65b8a8816160c622324b4f1aad55034e4a.tar.gz
Server support just requires exposing one constant for
setsockopt: Kgio::TCP_FASTOPEN

Client support implements a new Kgio::Socket#fastopen method.
This new method wraps the the sendto() syscall.  With TCP Fast
Open, the sendto() syscall is overloaded for stream sockets to
implement the functionality of both connect() + write()

Since it only makes sense to use _blocking_ I/O for sendto(),
TFO clients are only supported in Ruby implementations with
native threads.
Diffstat (limited to 'ext/kgio/kgio_ext.c')
-rw-r--r--ext/kgio/kgio_ext.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/ext/kgio/kgio_ext.c b/ext/kgio/kgio_ext.c
index 2365fd0..03b30e5 100644
--- a/ext/kgio/kgio_ext.c
+++ b/ext/kgio/kgio_ext.c
@@ -1,7 +1,42 @@
 #include "kgio.h"
+#include <sys/utsname.h>
+#include <stdio.h>
+/* true if TCP Fast Open is usable */
+unsigned kgio_tfo;
+
+static void tfo_maybe(void)
+{
+        VALUE mKgio = rb_define_module("Kgio");
+
+        /* Deal with the case where system headers have not caught up */
+        if (KGIO_TFO_MAYBE) {
+                /* Ensure Linux 3.7 or later for TCP_FASTOPEN */
+                struct utsname buf;
+                unsigned maj, min;
+
+                if (uname(&buf) != 0)
+                        rb_sys_fail("uname");
+                if (sscanf(buf.release, "%u.%u", &maj, &min) != 2)
+                        return;
+                if (maj < 3 || (maj == 3 && min < 7))
+                        return;
+        }
+
+        /*
+         * KGIO_TFO_MAYBE will be false if a distro backports TFO
+         * to a pre-3.7 kernel, but includes the necessary constants
+         * in system headers
+         */
+#if defined(MSG_FASTOPEN) && defined(TCP_FASTOPEN)
+        rb_define_const(mKgio, "TCP_FASTOPEN", INT2NUM(TCP_FASTOPEN));
+        rb_define_const(mKgio, "MSG_FASTOPEN", INT2NUM(MSG_FASTOPEN));
+        kgio_tfo = 1;
+#endif
+}
 
 void Init_kgio_ext(void)
 {
+        tfo_maybe();
         init_kgio_wait();
         init_kgio_read_write();
         init_kgio_connect();