1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| | # Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> 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
|