about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2012-03-05 23:19:29 +0000
committerEric Wong <normalperson@yhbt.net>2012-03-05 23:21:28 +0000
commit1129029ab1bf886979a66a69b04d244dba8b63cf (patch)
tree8dc3bf26b1446931430ef8e378cc9712f6118b2d
parent56cce133d979c22bbef80fdba1881d8f40876e2f (diff)
downloadkgio-1129029ab1bf886979a66a69b04d244dba8b63cf.tar.gz
It seems autopush support in our autopush code has
always been broken outside of Linux-based systems,
as we never marked the socket as having pending data.
-rw-r--r--ext/kgio/autopush.c1
-rw-r--r--ext/kgio/read_write.c13
-rw-r--r--test/test_autopush.rb3
3 files changed, 16 insertions, 1 deletions
diff --git a/ext/kgio/autopush.c b/ext/kgio/autopush.c
index 7c5553f..74576e8 100644
--- a/ext/kgio/autopush.c
+++ b/ext/kgio/autopush.c
@@ -240,6 +240,7 @@ static void push_pending_data(VALUE io)
 }
 #else /* !KGIO_NOPUSH */
 void kgio_autopush_recv(VALUE io){}
+void kgio_autopush_send(VALUE io){}
 void init_kgio_autopush(void)
 {
 }
diff --git a/ext/kgio/read_write.c b/ext/kgio/read_write.c
index 6f739a5..9c2440e 100644
--- a/ext/kgio/read_write.c
+++ b/ext/kgio/read_write.c
@@ -13,8 +13,18 @@ static ID id_set_backtrace;
 #if defined(__linux__) && ! defined(USE_MSG_DONTWAIT)
 #  define USE_MSG_DONTWAIT
 static const int peek_flags = MSG_DONTWAIT|MSG_PEEK;
+
+/* we don't need these variants, we call kgio_autopush_send/recv directly */
+static inline void kgio_autopush_read(VALUE io) { }
+static inline void kgio_autopush_write(VALUE io) { }
+
 #else
 static const int peek_flags = MSG_PEEK;
+#  include <netinet/tcp.h>
+#  if defined(TCP_NOPUSH)
+static inline void kgio_autopush_read(VALUE io) { kgio_autopush_recv(io); }
+static inline void kgio_autopush_write(VALUE io) { kgio_autopush_send(io); }
+#  endif
 #endif
 
 NORETURN(static void raise_empty_bt(VALUE, const char *));
@@ -112,6 +122,7 @@ static VALUE my_read(int io_wait, int argc, VALUE *argv, VALUE io)
         long n;
 
         prepare_read(&a, argc, argv, io);
+        kgio_autopush_read(io);
 
         if (a.len > 0) {
                 set_nonblocking(a.fd);
@@ -357,6 +368,8 @@ retry:
         n = (long)write(a.fd, a.ptr, a.len);
         if (write_check(&a, n, "write", io_wait) != 0)
                 goto retry;
+        if (TYPE(a.buf) != T_SYMBOL)
+                kgio_autopush_write(io);
         return a.buf;
 }
 
diff --git a/test/test_autopush.rb b/test/test_autopush.rb
index 24b300f..57fbefa 100644
--- a/test/test_autopush.rb
+++ b/test/test_autopush.rb
@@ -38,7 +38,8 @@ class TestAutopush < Test::Unit::TestCase
     assert_nothing_raised { s.kgio_write 'asdf' }
     assert_equal :wait_readable, s.kgio_tryread(1)
     assert s.kgio_autopush?
-    assert_equal 1, s.getsockopt(Socket::IPPROTO_TCP, opt).unpack('i')[0]
+    val = s.getsockopt(Socket::IPPROTO_TCP, opt).unpack('i')[0]
+    assert_operator val, :>, 0, "#{opt}=#{val} (#{RUBY_PLATFORM})"
   end
 
   def test_autopush_true_unix