diff options
author | Eric Wong <e@80x24.org> | 2016-02-25 09:34:08 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-02-25 09:41:27 +0000 |
commit | 83b7b3ef9582b05462b851571cf9dce44276b88c (patch) | |
tree | 83849e75ad82183550cbc04860106dae9458fca5 | |
parent | 1ac312ae86fb047613ff8558dd8f6ad43ae2ac59 (diff) | |
download | raindrops-83b7b3ef9582b05462b851571cf9dce44276b88c.tar.gz |
With invalid addresses specified which give no currently-bound address, we must avoid leaving placeholders ('true' objects) in our results. Clean up some shadowing "cur" while we're at it.
-rw-r--r-- | ext/raindrops/linux_inet_diag.c | 15 | ||||
-rw-r--r-- | test/test_linux.rb | 7 |
2 files changed, 19 insertions, 3 deletions
diff --git a/ext/raindrops/linux_inet_diag.c b/ext/raindrops/linux_inet_diag.c index 35bb127..58415c6 100644 --- a/ext/raindrops/linux_inet_diag.c +++ b/ext/raindrops/linux_inet_diag.c @@ -618,6 +618,13 @@ static VALUE tcp_stats(struct nogvl_args *args, VALUE addr) return rb_listen_stats(&args->stats); } +static int drop_placeholders(st_data_t k, st_data_t v, st_data_t ign) +{ + if ((VALUE)v == Qtrue) + return ST_DELETE; + return ST_CONTINUE; +} + /* * call-seq: * Raindrops::Linux.tcp_listener_stats([addrs[, sock]]) => hash @@ -658,10 +665,9 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self) case T_ARRAY: { long i; long len = RARRAY_LEN(addrs); - VALUE cur; if (len == 1) { - cur = rb_ary_entry(addrs, 0); + VALUE cur = rb_ary_entry(addrs, 0); rb_hash_aset(rv, cur, tcp_stats(&args, cur)); return rv; @@ -671,7 +677,7 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self) VALUE cur = rb_ary_entry(addrs, i); parse_addr(&check, cur); - rb_hash_aset(rv, cur, Qtrue); + rb_hash_aset(rv, cur, Qtrue /* placeholder */); } /* fall through */ } @@ -689,6 +695,9 @@ static VALUE tcp_listener_stats(int argc, VALUE *argv, VALUE self) st_foreach(args.table, NIL_P(addrs) ? st_to_hash : st_AND_hash, rv); st_free_table(args.table); + if (RHASH_SIZE(rv) > 1) + rb_hash_foreach(rv, drop_placeholders, Qfalse); + /* let GC deal with corner cases */ if (argc < 2) rb_io_close(sock); return rv; diff --git a/test/test_linux.rb b/test/test_linux.rb index 0e79a86..bfefcc4 100644 --- a/test/test_linux.rb +++ b/test/test_linux.rb @@ -214,6 +214,13 @@ class TestLinux < Test::Unit::TestCase assert_equal 0, stats[addr1].active assert_equal 1, stats[addr2].queued assert_equal 1, stats[addr2].active + + # make sure we don't leave "true" placeholders in results if a + # listener becomes invalid (even momentarily). + s2.close + stats = tcp_listener_stats(addrs) + assert stats.values.all? { |x| x.instance_of?(Raindrops::ListenStats) }, + "placeholders left: #{stats.inspect}" end # tries to overflow buffers |