about summary refs log tree commit homepage
path: root/lib/yahns/acceptor.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yahns/acceptor.rb')
-rw-r--r--lib/yahns/acceptor.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/yahns/acceptor.rb b/lib/yahns/acceptor.rb
new file mode 100644
index 0000000..b5e7b0e
--- /dev/null
+++ b/lib/yahns/acceptor.rb
@@ -0,0 +1,28 @@
+# 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)
+    accept_flags = Kgio::SOCK_NONBLOCK | Kgio::SOCK_CLOEXEC
+    Thread.new do
+      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
+        Yahns::Log.exception(logger, "accept loop error", e) unless closed?
+      end until closed?
+    end
+  end
+end