[PATCH] doc: expand on the SELF_PIPE description

Eric Wong normalperson at yhbt.net
Wed Oct 7 18:05:48 EDT 2009

There seems to be a small amount of confusion regarding how it's
used (and some of the code is not very obvious).  So explain our
usage of it and distinguish its use in the master vs worker(s).

  Hi Ryan,

  Great article[1] on Unicorn!  I just noticed a small misunderstanding
  in how SELF_PIPE is used by the workers, so I just updated the RDoc to
  hopefully better describe it.  I believe Unicorn is a great way to
  introduce Unix systems programming and you writing a great article is
  helping a lot :>

  As far as workers going down quickly in case the master dies
  unexpectedly: this is usually handled by checking the parent PID in
  the worker loop (which has a normal[2] upper bound of
  timeout(=default=60)/2.0 seconds per iteration on an idle server).
  Needing to get the workers to go down more quickly than that wasn't
  too important to us, so I made the decision to not get fancier.

  [1] - for those on the mailing list who haven't seen it:

  [2] - for the case where speculative accept() is constantly
        successful, then this could be infinity as long as requests
        keep flowing in faster than they can be processed.
	      Not that I expect anybody to care or hit this case
        (unexpectedly dead masters are very uncommon already :>).

 lib/unicorn.rb |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index ddec8e9..d63567f 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -42,7 +42,23 @@ module Unicorn
     # This hash maps PIDs to Workers
     WORKERS = {}
-    # See: http://cr.yp.to/docs/selfpipe.html
+    # We use SELF_PIPE differently in the master and worker processes:
+    #
+    # * The master process never closes or reinitializes this once
+    # initialized.  Signal handlers in the master process will write to
+    # it to wake up the master from IO.select in exactly the same manner
+    # djb describes in http://cr.yp.to/docs/selfpipe.html
+    #
+    # * The workers immediately close the pipe they inherit from the
+    # master and replace it with a new pipe after forking.  This new
+    # pipe is also used to wakeup from IO.select from inside (worker)
+    # signal handlers.  However, workers *close* the pipe descriptors in
+    # the signal handlers to raise EBADF in IO.select instead of writing
+    # like we do in the master.  We cannot easily use the reader set for
+    # IO.select because LISTENERS is already that set, and it's extra
+    # work (and cycles) to distinguish the pipe FD from the reader set
+    # once IO.select returns.  So we're lazy and just close the pipe when
+    # a (rare) signal arrives in the worker and reinitialize the pipe later.
     SELF_PIPE = []
     # signal queue used for self-piping
Eric Wong

More information about the mongrel-unicorn mailing list