about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/yahns/server.rb31
1 files changed, 22 insertions, 9 deletions
diff --git a/lib/yahns/server.rb b/lib/yahns/server.rb
index 3ba7537..b66d208 100644
--- a/lib/yahns/server.rb
+++ b/lib/yahns/server.rb
@@ -359,16 +359,29 @@ class Yahns::Server # :nodoc:
     alive
   end
 
+  # return true if any acceptor is still alive, false otherwise
   def acceptors_alive
-    @athr.delete_if do |t|
-      # blocking accept() does not wake up on, close() only EINTR and
-      # new connections.  So Thread#run will send SIGVTALRM via
-      # pthread_kill, which will break it out of blocking syscalls
-      # like accept()
-      # if t.run fails, thread is dead
-      t.run rescue nil
-      t.join(1)
-    end.size > 0
+    case RUBY_ENGINE
+    when "rbx"
+      false # XXX this needs to be diagnosed and fixed for rbx
+    else
+      # We should stop acceptors before stopping queues.  Closing the
+      # acceptor socket is not sufficient to stop the last client of
+      # each thread fom being accepted and thrown into the queue.
+      @athr.delete_if do |t|
+        # blocking accept() does not wake up on, close() only EINTR and
+        # new connections.  So Thread#run will send SIGVTALRM via
+        # pthread_kill, which will break it out of blocking syscalls
+        # like accept()
+        t.run rescue nil # if .run fails, thread is dead and joinable
+        begin
+          t.join(0.1)
+        rescue => e
+          Yahns::Log.exception(@logger, "acceptor shutdown", e)
+          true
+        end
+      end.size > 0
+    end
   end
 
   # single-threaded only, this is overriden if @worker_processes is non-nil