# Copyright (C) 2013, Eric Wong et. al. # License: GPLv3 or later (see COPYING for details) module Yahns::Acceptor # :nodoc: def spawn_acceptor(logger, client_class, queue) Thread.new do accept_flags = Kgio::SOCK_NONBLOCK | Kgio::SOCK_CLOEXEC Thread.current.abort_on_exception = true qev_flags = client_class.superclass::QEV_FLAGS begin # We want the accept/accept4 syscall to be _blocking_ # so it can distribute work evenly between processes if client = kgio_accept(client_class, accept_flags) client.yahns_init # it is not safe to touch client in this thread after this, # a worker thread may grab client right away queue.queue_add(client, qev_flags) end rescue Errno::EMFILE, Errno::ENFILE => e logger.error("#{e.message}, consider raising open file limits") queue.fdmap.desperate_expire_for(self, 5) sleep 1 # let other threads do some work rescue => e # sleep since this check is racy (and uncommon) break if closed? || (sleep(0.01) && closed?) Yahns::Log.exception(logger, "accept loop", e) end while true end end end