From: Eric Wong <normalperson@yhbt.net>
To: mongrel-unicorn@rubyforge.org
Subject: listen loop error in 4.8.0
Date: Mon, 27 Jan 2014 16:56:40 +0000 [thread overview]
Message-ID: <20140127165640.GA7074@dcvr.yhbt.net> (raw)
Hey all, I'm trying to diagnose an issue with another user over
private email.
It seems io.close in the trap(:QUIT) handler of the worker process is
causing an IOError, which means an IO in the readers array already got
closed somehow. This shouldn't happen, and CRuby 2.x doesn't seem
to interrupt itself inside signal handlers[1].
Below is what I have so far...
Worst case is we're not any worse off than before; but we
could be hiding another bug with the "rescue nil" on io.close.
An extra set of eyes would be appreciated.
Pushed to the llerrloop branch of git://bogomips.org/unicorn.git
Also on rubygems.org: gem install --pre -v 4.8.0.1.g10a2 unicorn
[1] - however other Ruby runtimes may.
Subject: [PATCH] http_server: safer SIGQUIT handler for worker
This protects us from two potential errors:
1) we (or our app) somehow called IO#close on one of the sockets
we listen on without removing it from the readers array.
We'll ignore IOErrors from IO#close and assume we wanted to
close it.
2) our SIGQUIT handler is interrupted by itself. This is currently
not possible with (MRI) Ruby 2.x, but it may happen in other
implementations (as it does in normal C code).
---
lib/unicorn/http_server.rb | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/unicorn/http_server.rb b/lib/unicorn/http_server.rb
index ae8ad13..2052d53 100644
--- a/lib/unicorn/http_server.rb
+++ b/lib/unicorn/http_server.rb
@@ -591,6 +591,13 @@ class Unicorn::HttpServer
EXIT_SIGS = [ :QUIT, :TERM, :INT ]
WORKER_QUEUE_SIGS = QUEUE_SIGS - EXIT_SIGS
+ def nuke_listeners!(readers)
+ # only called from the worker, ordering is important here
+ tmp = readers.dup
+ readers.replace([false]) # ensure worker does not continue ASAP
+ tmp.each { |io| io.close rescue nil } # break out of IO.select
+ end
+
# gets rid of stuff the worker has no business keeping track of
# to free some resources and drops all sig handlers.
# traps for USR1, USR2, and HUP may be set in the after_fork Proc
@@ -618,7 +625,7 @@ class Unicorn::HttpServer
@after_fork = @listener_opts = @orig_app = nil
readers = LISTENERS.dup
readers << worker
- trap(:QUIT) { readers.each { |io| io.close }.replace([false]) }
+ trap(:QUIT) { nuke_listeners!(readers) }
readers
end
@@ -677,7 +684,7 @@ class Unicorn::HttpServer
worker.tick = Time.now.to_i
ret = IO.select(readers, nil, nil, @timeout) and ready = ret[0]
rescue => e
- redo if nr < 0
+ redo if nr < 0 && readers[0]
Unicorn.log_error(@logger, "listen loop error", e) if readers[0]
end while readers[0]
end
--
1.8.5.3.368.gab0bcec
_______________________________________________
Unicorn mailing list - mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn
Do not quote signatures (like this one) or top post when replying
next reply other threads:[~2014-01-27 16:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-27 16:56 Eric Wong [this message]
2014-01-27 17:02 ` listen loop error in 4.8.0 Eric Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://yhbt.net/unicorn/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140127165640.GA7074@dcvr.yhbt.net \
--to=normalperson@yhbt.net \
--cc=mongrel-unicorn@rubyforge.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhbt.net/unicorn.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).