  require 'socket'
  mode= ARGV[0]
  fds= ->{ Dir.children('/proc/self/fd').size }
  stats= Hash.new(0); n= 300; fd0= fds.()
  n.times do
    l= TCPServer.new '127.0.0.1', 0
    socks= []
    th= Thread.new { begin; loop { s= l.accept; socks<< s }; rescue IOError, SystemCallError; end }
    c= TCPSocket.new '127.0.0.1', l.addr[1]
    case mode
    when 'shutdown-join-close' then (l.shutdown rescue nil); th.join; l.close
    when 'shutdown' then (l.shutdown rescue nil); l.close; th.join
    else l.close; th.join
    end
    socks.each(&:close)
    r= IO.select [c], nil, nil, 0.5
    stats[[r ? :ok : :hang, socks.empty? ? :not_accepted : :accepted]]+= 1
    c.close
  end
  GC.start
  puts "#{mode}: #{stats.inspect}  fd delta after GC: #{fds.()- fd0}"
