*epoll: refactor common loop code
[rainbows.git] / lib / rainbows / xepoll / client.rb
blobda0a0d17d4b20f3f7786a196188df0f89ef17e76
1 # -*- encoding: binary -*-
2 # :enddoc:
4 module Rainbows::XEpoll::Client
5   N = Raindrops.new(1)
6   Rainbows::Epoll.nr_clients = lambda { N[0] }
7   include Rainbows::Epoll::Client
8   MAX = Rainbows.server.worker_connections
9   THRESH = MAX - 1
10   EP = Rainbows::Epoll::EP
11   THREADS = Rainbows::HttpServer::LISTENERS.map do |sock|
12     Thread.new(sock) do |sock|
13       sleep
14       begin
15         if io = sock.kgio_accept
16           N.incr(0, 1)
17           io.epoll_once
18         end
19         sleep while N[0] >= MAX
20       rescue => e
21         Rainbows::Error.listen_loop(e)
22       end while Rainbows.alive
23     end
24   end
26   def self.run
27     THREADS.each { |t| t.run }
28     Rainbows::Epoll.loop
29     Rainbows::JoinThreads.acceptors(THREADS)
30   end
32   # only call this once
33   def epoll_once
34     @wr_queue = [] # may contain String, ResponsePipe, and StreamFile objects
35     post_init
36     EP.set(self, IN) # wake up the main thread
37     rescue => e
38       Rainbows::Error.write(self, e)
39   end
41   def on_close
42     KATO.delete(self)
43     N.decr(0, 1) == THRESH and THREADS.each { |t| t.run }
44   end
45 end