From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.9 required=3.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: raindrops-public@bogomips.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 4687E63381A; Thu, 25 Feb 2016 09:54:32 +0000 (UTC) Date: Thu, 25 Feb 2016 09:54:32 +0000 From: Eric Wong To: Hleb Valoshka <375gnu@gmail.com> Cc: raindrops-public@bogomips.org Subject: Re: [PATCH 2/2] Return real stats instead of True Message-ID: <20160225095432.GA21370@dcvr.yhbt.net> References: <1378753439-13495-1-git-send-email-375GNU@Gmail.COM> <1378753439-13495-2-git-send-email-375GNU@Gmail.COM> <20130909192020.GA18010@dcvr.yhbt.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20130909192020.GA18010@dcvr.yhbt.net> List-Id: Eric Wong wrote: > Hleb Valoshka <375gnu@gmail.com> wrote: > > > > This deserves an explanation (and ideally, a test case). I haven't > looked at the code in a while and needed to think a bit about > when the fix is relevant. Resurrecting this from the old list 2.5 years ago: http://bogomips.org/raindrops-public/20130909192020.GA18010@dcvr.yhbt.net/t/#u I actually found a different reason for this problem. Normally, I never change the set of listeners. But lately I've been switching between backend HTTP servers that needed to run over TCP (as opposed to Unix sockets) and dropping listeners occasionally was causing "true" to show up in the results. -----------8<------------ Subject: [PATCH] linux: tcp_listener_stats drops "true" placeholders 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. --- ext/raindrops/linux_inet_diag.c | 15 ++++++++++++--- 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 @@ def test_tcp_multi 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 -- EW