diff options
-rw-r--r-- | ext/raindrops/linux_inet_diag.c | 4 | ||||
-rw-r--r-- | test/test_linux_reuseport_tcp_listen_stats.rb | 51 |
2 files changed, 53 insertions, 2 deletions
diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c index cabd427..2a2360c 100644 --- a/ext/raindrops/linux_inet_diag.c +++ b/ext/raindrops/linux_inet_diag.c @@ -306,7 +306,7 @@ static void table_set_queued(st_table *table, struct inet_diag_msg *r) { struct listen_stats *stats = stats_for(table, r); stats->listener_p = 1; - stats->queued = r->idiag_rqueue; + stats->queued += r->idiag_rqueue; } /* inner loop of inet_diag, called for every socket returned by netlink */ @@ -328,7 +328,7 @@ static inline void r_acc(struct nogvl_args *args, struct inet_diag_msg *r) if (args->table) table_set_queued(args->table, r); else - args->stats.queued = r->idiag_rqueue; + args->stats.queued += r->idiag_rqueue; } /* * we wont get anything else because of the idiag_states filter diff --git a/test/test_linux_reuseport_tcp_listen_stats.rb b/test/test_linux_reuseport_tcp_listen_stats.rb new file mode 100644 index 0000000..c977c43 --- /dev/null +++ b/test/test_linux_reuseport_tcp_listen_stats.rb @@ -0,0 +1,51 @@ +# -*- encoding: binary -*- +require "./test/rack_unicorn" +require 'test/unit' +require 'socket' +require 'raindrops' +$stderr.sync = $stdout.sync = true + +class TestLinuxReuseportTcpListenStats < Test::Unit::TestCase + include Raindrops::Linux + include Unicorn::SocketHelper + TEST_ADDR = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1' + DEFAULT_BACKLOG = 10 + + def setup + @socks = [] + end + + def teardown + @socks.each { |io| io.closed? or io.close } + end + + def new_socket_server(**kwargs) + s = new_tcp_server TEST_ADDR, kwargs[:port] || 0, kwargs + s.listen(kwargs[:backlog] || DEFAULT_BACKLOG) + @socks << s + [ s, s.addr[1] ] + end + + def new_client(port) + s = TCPSocket.new("127.0.0.1", port) + @socks << s + s + end + + def test_reuseport_queue_stats + listeners = 10 + _, port = new_socket_server(reuseport: true) + addr = "#{TEST_ADDR}:#{port}" + listeners.times do + new_socket_server(reuseport: true, port: port) + end + + listeners.times do |i| + all = Raindrops::Linux.tcp_listener_stats + assert_equal [0, i], all[addr].to_a + new_client(port) + all = Raindrops::Linux.tcp_listener_stats + assert_equal [0, i+1], all[addr].to_a + end + end +end if RUBY_PLATFORM =~ /linux/ |