From 37e50a9a5fcd45242373379c0dc61ebf8ff609af Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 31 Jan 2011 18:27:24 -0800 Subject: autopush: enable accessors for client sockets Might as well allow clients to efficiently handle TCP_CORK/TCP_NOPUSH, too. --- ext/kgio/autopush.c | 32 ++++++++++++++++++++++++++++---- test/test_autopush.rb | 14 ++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/ext/kgio/autopush.c b/ext/kgio/autopush.c index a91e019..058e202 100644 --- a/ext/kgio/autopush.c +++ b/ext/kgio/autopush.c @@ -90,12 +90,36 @@ static VALUE s_set_autopush(VALUE self, VALUE val) return val; } +static VALUE autopush_get(VALUE io) +{ + return state_get(io) <= 0 ? Qfalse : Qtrue; +} + +static VALUE autopush_set(VALUE io, VALUE vbool) +{ + int fd = my_fileno(io); + int val; + socklen_t len = sizeof(val); + + if (RTEST(vbool)) + state_set(io, AUTOPUSH_STATE_WRITER); + else + state_set(io, AUTOPUSH_STATE_IGNORE); + return vbool; +} + void init_kgio_autopush(void) { - VALUE m = rb_define_module("Kgio"); + VALUE mKgio = rb_define_module("Kgio"); + VALUE tmp; + + rb_define_singleton_method(mKgio, "autopush?", s_get_autopush, 0); + rb_define_singleton_method(mKgio, "autopush=", s_set_autopush, 1); + + tmp = rb_define_module_under(mKgio, "SocketMethods"); + rb_define_method(tmp, "kgio_autopush=", autopush_set, 1); + rb_define_method(tmp, "kgio_autopush?", autopush_get, 0); - rb_define_singleton_method(m, "autopush?", s_get_autopush, 0); - rb_define_singleton_method(m, "autopush=", s_set_autopush, 1); id_autopush_state = rb_intern("@kgio_autopush_state"); } @@ -170,7 +194,7 @@ static void push_pending_data(VALUE io) /* immediately recork */ optval = 1; if (setsockopt(fd, IPPROTO_TCP, KGIO_NOPUSH, &optval, optlen) != 0) - rb_sys_fail("setsockopt(TCP_CORK, 1)"); + rb_sys_fail("setsockopt(TCP_CORK/TCP_NOPUSH, 1)"); } #else /* !KGIO_NOPUSH */ void init_kgio_autopush(void) diff --git a/test/test_autopush.rb b/test/test_autopush.rb index 4d15b7b..bbd4b46 100644 --- a/test/test_autopush.rb +++ b/test/test_autopush.rb @@ -23,6 +23,20 @@ class TestAutopush < Test::Unit::TestCase @port = @srv.addr[1] end + def test_autopush_accessors + Kgio.autopush = true + opt = RUBY_PLATFORM =~ /freebsd/ ? TCP_NOPUSH : TCP_CORK + s = Kgio::TCPSocket.new(@host, @port) + assert_equal 0, s.getsockopt(Socket::IPPROTO_TCP, opt).unpack('i')[0] + assert ! s.kgio_autopush? + s.kgio_autopush = true + assert s.kgio_autopush? + 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] + end + def test_autopush_true_unix Kgio.autopush = true tmp = Tempfile.new('kgio_unix') -- cgit v1.2.3-24-ge0c7