class Puma::Server
def handle_servers
def handle_servers begin check = @check sockets = [check] + @binder.ios pool = @thread_pool queue_requests = @queue_requests drain = @options[:drain_on_shutdown] ? 0 : nil addr_send_name, addr_value = case @options[:remote_address] when :value [:peerip=, @options[:remote_address_value]] when :header [:remote_addr_header=, @options[:remote_address_header]] when :proxy_protocol [:expect_proxy_proto=, @options[:remote_address_proxy_protocol]] else [nil, nil] end while @status == :run || (drain && shutting_down?) begin ios = IO.select sockets, nil, nil, (shutting_down? ? 0 : @idle_timeout) unless ios unless shutting_down? @idle_timeout_reached = true if @clustered @worker_write << "i#{Process.pid}\n" rescue nil next else @log_writer.log "- Idle timeout reached" @status = :stop end end break end if @idle_timeout_reached && @clustered @idle_timeout_reached = false @worker_write << "i#{Process.pid}\n" rescue nil end ios.first.each do |sock| if sock == check break if handle_check else pool.wait_until_not_full pool.wait_for_less_busy_worker(@options[:wait_for_less_busy_worker]) io = begin sock.accept_nonblock rescue IO::WaitReadable next end drain += 1 if shutting_down? pool << Client.new(io, @binder.env(sock)).tap { |c| c.listener = sock c.http_content_length_limit = @http_content_length_limit c.send(addr_send_name, addr_value) if addr_value } end end rescue IOError, Errno::EBADF # In the case that any of the sockets are unexpectedly close. raise rescue StandardError => e @log_writer.unknown_error e, nil, "Listen loop" end end @log_writer.debug "Drained #{drain} additional connections." if drain @events.fire :state, @status if queue_requests @queue_requests = false @reactor.shutdown end graceful_shutdown if @status == :stop || @status == :restart rescue Exception => e @log_writer.unknown_error e, nil, "Exception handling servers" ensure # Errno::EBADF is infrequently raised [@check, @notify].each do |io| begin io.close unless io.closed? rescue Errno::EBADF end end @notify = nil @check = nil end @events.fire :state, :done end