1 # -*- encoding: binary -*-
5 # Implements a worker thread pool model. This is suited for platforms
6 # where the cost of dynamically spawning a new thread for every new
7 # client connection is too high.
9 # Applications using this model are required to be thread-safe.
10 # Threads are never spawned dynamically under this model. If you're
11 # connecting to external services and need to perform DNS lookups,
12 # consider using the "resolv-replace" library which replaces parts of
13 # the core Socket package with concurrent DNS lookup capabilities.
15 # This model is less suited for many slow clients than the others and
16 # thus a lower +worker_connections+ setting is recommended.
21 def worker_loop(worker)
22 init_worker_process(worker)
23 RACK_DEFAULTS["rack.multithread"] = true
24 pool = (1..worker_connections).map { new_worker_thread }
27 while LISTENERS.first && master_pid == Process.ppid
29 worker.tmp.chmod(m = 0 == m ? 1 : 0)
30 # if any worker dies, something is serious wrong, bail
31 thr.join(timeout) and break
34 join_threads(pool, worker)
41 ret = IO.select(LISTENERS, nil, nil, timeout) or next
42 ret.first.each do |sock|
44 process_client(sock.accept_nonblock)
45 rescue Errno::EAGAIN, Errno::ECONNABORTED
50 rescue Errno::EBADF, TypeError
54 listen_loop_error(e) if LISTENERS.first
55 end while ! Thread.current[:quit] && LISTENERS.first