Dear Scott,

I don't like the limitations of your patch, and I think I've come up with a much cleaner solution. The attached UNTESTED diff should apply cleanly against SVN HEAD. Please let me know if it works, and I would
really appreciate a test case (or a few, for the different threading
modes), as this does seem a bit convoluted and there might be corner
cases I overlooked. And after all, the last thing you want for a zero-downtime deployment is crashing code ;-).

Especially with a test, I can see this going into MHD relatively quickly ;-).


Happy hacking!

Christian

On 04/25/2013 10:31 AM, Scott J. Goldman wrote:
Hi.

Where I work, we do continuous deployment of services, so it's important to us 
to be able to be able to deploy new code and restart our services in a way that 
doesn't cause downtime. One of the ways we do that is by deploying daemons 
which can fork-exec themselves and inherit the listening socket. With a 
slightly modified libmicrohttpd, we implemented this functionality. It works 
like this:
1. send SIGUSR1 to the daemon
2. daemon fork-exec's a new version of itself, passing the fd# of the listening 
socket, and a status pipe via command-line args
3. new daemon initializes, starts accepting connections on the socket (with 
MHD_OPTION_LISTEN_SOCKET), and sends a message via the status pipe
4. old daemon operates normally until it gets the status message, and then 
stops accept()ing new connections, but continues processing old ones
5. old daemon finishes processing all remaining clients, and terminates

libmicrohttpd had nearly all the functionality we needed, except for having the 
"quiesce" functionality, to stop accept()'ing new connections, while continuing 
to process existing clients. I'm wondering if you would consider this feature for 
inclusion in your mainline version of the library. I've included a link to our patch 
below that is our rough attempt to hack in this functionality. I would be happy to revise 
it with your feedback.

https://gist.github.com/scottjg/5458005
https://gist.github.com/scottjg/5458005/raw/4ad505101f80485e24a6a2f1092f173706749df3/quiesce-api.patch

The main issue with the patch is that calling shutdown() on the listening 
socket is no longer acceptable in this mode. On Linux, calling shutdown() in 
the old daemon will prevent the new daemon from being able to accept() new 
clients. For our purposes we used the alternate pipe method to wake up the 
event loop, which appears to works fine.

Cheers,
-sjg
Index: doc/texinfo.tex
===================================================================
--- doc/texinfo.tex	(revision 26980)
+++ doc/texinfo.tex	(working copy)
@@ -3,7 +3,7 @@
 % Load plain if necessary, i.e., if running under initex.
 \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
 %
-\def\texinfoversion{2012-09-05.06}
+\def\texinfoversion{2012-03-11.15}
 %
 % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
 % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
@@ -28,9 +28,9 @@
 %
 % Please try the latest version of texinfo.tex before submitting bug
 % reports; you can get the latest version from:
-%   http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or
-%   http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or
-%   http://www.gnu.org/software/texinfo/ (the Texinfo home page)
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
 % The texinfo.tex in any given distribution could well be out
 % of date, so if that's what you're using, please check.
 %
@@ -594,7 +594,7 @@
 \def\:{\spacefactor=1000 }
 
 % @* forces a line break.
-\def\*{\unskip\hfil\break\hbox{}\ignorespaces}
+\def\*{\hfil\break\hbox{}\ignorespaces}
 
 % @/ allows a line break.
 \let\/=\allowbreak
@@ -1117,7 +1117,7 @@
 % #1 is a control sequence in which to do the replacements,
 % which we \xdef.
 \def\txiescapepdf#1{%
-  \ifx\pdfescapestring\thisisundefined
+  \ifx\pdfescapestring\relax
     % No primitive available; should we give a warning or log?
     % Many times it won't matter.
   \else
@@ -1367,8 +1367,9 @@
   \def\skipspaces#1{\def\PP{#1}\def\D{|}%
     \ifx\PP\D\let\nextsp\relax
     \else\let\nextsp\skipspaces
-      \addtokens{\filename}{\PP}%
-      \advance\filenamelength by 1
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
     \fi
     \nextsp}
   \def\getfilename#1{%
@@ -1474,6 +1475,9 @@
 \def\ttsl{\setfontstyle{ttsl}}
 
 
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
 % Set the baselineskip to #1, and the lineskip and strut size
 % correspondingly.  There is no deep meaning behind these magic numbers
 % used as factors; they just match (closely enough) what Knuth defined.
@@ -1485,7 +1489,6 @@
 % can get a sort of poor man's double spacing by redefining this.
 \def\baselinefactor{1}
 %
-\newdimen\textleading
 \def\setleading#1{%
   \dimen0 = #1\relax
   \normalbaselineskip = \baselinefactor\dimen0
@@ -1758,24 +1761,18 @@
 \fi\fi
 
 
-% Set the font macro #1 to the font named \fontprefix#2.
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
 % #3 is the font's design size, #4 is a scale factor, #5 is the CMap
-% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit).
-% Example:
-% #1 = \textrm
-% #2 = \rmshape
-% #3 = 10
-% #4 = \mainmagstep
-% #5 = OT1
-%
+% encoding (currently only OT1, OT1IT and OT1TT are allowed, pass
+% empty to omit).
 \def\setfont#1#2#3#4#5{%
   \font#1=\fontprefix#2#3 scaled #4
   \csname cmap#5\endcsname#1%
 }
 % This is what gets called when #5 of \setfont is empty.
 \let\cmap\gobble
-%
-% (end of cmaps)
+% emacs-page end of cmaps
 
 % Use cm as the default font prefix.
 % To specify the font prefix, you must define \fontprefix
@@ -1785,7 +1782,7 @@
 \fi
 % Support font families that don't use the same naming scheme as CM.
 \def\rmshape{r}
-\def\rmbshape{bx}               % where the normal face is bold
+\def\rmbshape{bx}               %where the normal face is bold
 \def\bfshape{b}
 \def\bxshape{bx}
 \def\ttshape{tt}
@@ -1800,7 +1797,8 @@
 \def\scshape{csc}
 \def\scbshape{csc}
 
-% Definitions for a main text size of 11pt.  (The default in Texinfo.)
+% Definitions for a main text size of 11pt.  This is the default in
+% Texinfo.
 %
 \def\definetextfontsizexi{%
 % Text fonts (11.2pt, magstep1).
@@ -1925,7 +1923,7 @@
 \textleading = 13.2pt % line spacing for 11pt CM
 \textfonts            % reset the current fonts
 \rm
-} % end of 11pt text font size definitions, \definetextfontsizexi
+} % end of 11pt text font size definitions
 
 
 % Definitions to make the main text be 10pt Computer Modern, with
@@ -2057,7 +2055,7 @@
 \textleading = 12pt   % line spacing for 10pt CM
 \textfonts            % reset the current fonts
 \rm
-} % end of 10pt text font size definitions, \definetextfontsizex
+} % end of 10pt text font size definitions
 
 
 % We provide the user-level command
@@ -2448,12 +2446,34 @@
 % @samp.
 \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}}
 
-% @indicateurl is \samp, that is, with quotes.
-\let\indicateurl=\samp
+% definition of @key that produces a lozenge.  Doesn't adjust to text size.
+%\setfont\keyrm\rmshape{8}{1000}{OT1}
+%\font\keysy=cmsy9
+%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+%  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+%    \vbox{\hrule\kern-0.4pt
+%     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+%    \kern-0.4pt\hrule}%
+%  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
 
-% @code (and similar) prints in typewriter, but with spaces the same
-% size as normal in the surrounding text, without hyphenation, etc.
-% This is a subroutine for that.
+% definition of @key with no lozenge.  If the current font is already
+% monospace, don't change it; that way, we respect @kbdinputstyle.  But
+% if it isn't monospace, then use \tt.
+%
+\def\key#1{{\setupmarkupstyle{key}%
+  \nohyphenation
+  \ifmonospace\else\tt\fi
+  #1}\null}
+
+% ctrl is no longer a Texinfo command.
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
 \def\tclose#1{%
   {%
     % Change normal interword space to be same as for the current font.
@@ -2478,7 +2498,7 @@
 % We *must* turn on hyphenation at `-' and `_' in @code.
 % Otherwise, it is too hard to avoid overfull hboxes
 % in the Emacs manual, the Library manual, etc.
-%
+
 % Unfortunately, TeX uses one parameter (\hyphenchar) to control
 % both hyphenation at - and hyphenation within words.
 % We must therefore turn them both off (\tclose does that)
@@ -2542,13 +2562,6 @@
   \fi\fi
 }
 
-% For @command, @env, @file, @option quotes seem unnecessary,
-% so use \code rather than \samp.
-\let\command=\code
-\let\env=\code
-\let\file=\code
-\let\option=\code
-
 % @uref (abbreviation for `urlref') takes an optional (comma-separated)
 % second argument specifying the text to display and an optional third
 % arg as text to display instead of (rather than in addition to) the url
@@ -2728,25 +2741,11 @@
 \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi
 \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi}
 
-% definition of @key that produces a lozenge.  Doesn't adjust to text size.
-%\setfont\keyrm\rmshape{8}{1000}{OT1}
-%\font\keysy=cmsy9
-%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
-%  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
-%    \vbox{\hrule\kern-0.4pt
-%     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
-%    \kern-0.4pt\hrule}%
-%  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
 
-% definition of @key with no lozenge.  If the current font is already
-% monospace, don't change it; that way, we respect @kbdinputstyle.  But
-% if it isn't monospace, then use \tt.
-%
-\def\key#1{{\setupmarkupstyle{key}%
-  \nohyphenation
-  \ifmonospace\else\tt\fi
-  #1}\null}
-
 % @clicksequence{File @click{} Open ...}
 \def\clicksequence#1{\begingroup #1\endgroup}
 
@@ -2853,9 +2852,6 @@
   }
 }
 
-% ctrl is no longer a Texinfo command, but leave this definition for fun.
-\def\ctrl #1{{\tt \rawbackslash \hat}#1}
-
 % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}.
 % Ignore unless FMTNAME == tex; then it is like @iftex and @tex,
 % except specified as a normal braced arg, so no newlines to worry about.
@@ -3146,17 +3142,12 @@
   % hopefully nobody will notice/care.
   \edef\ecsize{\csname\curfontsize ecsize\endcsname}%
   \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}%
-  \ifmonospace
-    % typewriter:
-    \font\thisecfont = ectt\ecsize \space at \nominalsize
+  \ifx\curfontstyle\bfstylename
+    % bold:
+    \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
   \else
-    \ifx\curfontstyle\bfstylename
-      % bold:
-      \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize
-    \else
-      % regular:
-      \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
-    \fi
+    % regular:
+    \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize
   \fi
   \thisecfont
 }
@@ -3269,20 +3260,6 @@
   \finishedtitlepagetrue
 }
 
-% Settings used for typesetting titles: no hyphenation, no indentation,
-% don't worry much about spacing, ragged right.  This should be used
-% inside a \vbox, and fonts need to be set appropriately first.  Because
-% it is always used for titles, nothing else, we call \rmisbold.  \par
-% should be specified before the end of the \vbox, since a vbox is a group.
-% 
-\def\raggedtitlesettings{%
-  \rmisbold
-  \hyphenpenalty=10000
-  \parindent=0pt
-  \tolerance=5000
-  \ptexraggedright
-}
-
 % Macros to be used within @titlepage:
 
 \let\subtitlerm=\tenrm
@@ -3290,7 +3267,7 @@
 
 \parseargdef\title{%
   \checkenv\titlepage
-  \vbox{\titlefonts \raggedtitlesettings #1\par}%
+  \leftline{\titlefonts\rmisbold #1}
   % print a rule at the page bottom also.
   \finishedtitlepagefalse
   \vskip4pt \hrule height 4pt width \hsize \vskip4pt
@@ -4227,7 +4204,7 @@
 }
 \def\ifsetfail{\doignore{ifset}}
 
-% @ifclear VAR ... @end executes the `...' iff VAR has never been
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
 % defined with @set, or has been undefined with @clear.
 %
 % The `\else' inside the `\doifset' parameter is a trick to reuse the
@@ -4238,35 +4215,6 @@
 \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
 \def\ifclearfail{\doignore{ifclear}}
 
-% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written
-% without the @) is in fact defined.  We can only feasibly check at the
-% TeX level, so something like `mathcode' is going to considered
-% defined even though it is not a Texinfo command.
-% 
-\makecond{ifcommanddefined}
-\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}}
-%
-\def\doifcmddefined#1#2{{%
-    \makevalueexpandable
-    \let\next=\empty
-    \expandafter\ifx\csname #2\endcsname\relax
-      #1% If not defined, \let\next as above.
-    \fi
-    \expandafter
-  }\next
-}
-\def\ifcmddefinedfail{\doignore{ifcommanddefined}}
-
-% @ifcommandnotdefined CMD ... handlded similar to @ifclear above.
-\makecond{ifcommandnotdefined}
-\def\ifcommandnotdefined{%
-  \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}}
-\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}}
-
-% Set the `txicommandconditionals' variable, so documents have a way to
-% test if the @ifcommand...defined conditionals are available.
-\set txicommandconditionals
-
 % @dircategory CATEGORY  -- specify a category of the dir file
 % which this file should belong to.  Ignore this in TeX.
 \let\dircategory=\comment
@@ -4503,7 +4451,6 @@
   \definedummyword\guillemetright
   \definedummyword\guilsinglleft
   \definedummyword\guilsinglright
-  \definedummyword\lbracechar
   \definedummyword\leq
   \definedummyword\minus
   \definedummyword\ogonek
@@ -4516,7 +4463,6 @@
   \definedummyword\quoteleft
   \definedummyword\quoteright
   \definedummyword\quotesinglbase
-  \definedummyword\rbracechar
   \definedummyword\result
   \definedummyword\textdegree
   %
@@ -4568,7 +4514,6 @@
   \definedummyword\t
   %
   % Commands that take arguments.
-  \definedummyword\abbr
   \definedummyword\acronym
   \definedummyword\anchor
   \definedummyword\cite
@@ -4580,9 +4525,7 @@
   \definedummyword\emph
   \definedummyword\env
   \definedummyword\file
-  \definedummyword\image
   \definedummyword\indicateurl
-  \definedummyword\inforef
   \definedummyword\kbd
   \definedummyword\key
   \definedummyword\math
@@ -4629,10 +4572,7 @@
   % content at all.  So for index sorting, we map @{ and @} to strings
   % starting with |, since that ASCII character is between ASCII { and }.
   \def\{{|a}%
-  \def\lbracechar{|a}%
-  %
   \def\}{|b}%
-  \def\rbracechar{|b}%
   %
   % Non-English letters.
   \def\AA{AA}%
@@ -5593,6 +5533,14 @@
 
 % Define @majorheading, @heading and @subheading
 
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
 \def\majorheading{%
   {\advance\chapheadingskip by 10pt \chapbreak }%
   \parsearg\chapheadingzzz
@@ -5600,8 +5548,10 @@
 
 \def\chapheading{\chapbreak \parsearg\chapheadingzzz}
 \def\chapheadingzzz#1{%
-  \vbox{\chapfonts \raggedtitlesettings #1\par}%
-  \nobreak\bigskip \nobreak
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\ptexraggedright
+                    \rmisbold #1\hfill}}%
+  \bigskip \par\penalty 200\relax
   \suppressfirstparagraphindent
 }
 
@@ -5760,7 +5710,8 @@
     %
     % Typeset the actual heading.
     \nobreak % Avoid page breaks at the interline glue.
-    \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright
+          \hangindent=\wd0 \centerparametersmaybe
           \unhbox0 #1\par}%
   }%
   \nobreak\bigskip % no page break after a chapter title
@@ -5782,18 +5733,18 @@
 \def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
 %
 \def\unnchfopen #1{%
-  \chapoddpage
-  \vbox{\chapfonts \raggedtitlesettings #1\par}%
-  \nobreak\bigskip\nobreak
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\ptexraggedright
+                       \rmisbold #1\hfill}}\bigskip \par\nobreak
 }
 \def\chfopen #1#2{\chapoddpage {\chapfonts
 \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
 \par\penalty 5000 %
 }
 \def\centerchfopen #1{%
-  \chapoddpage
-  \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}%
-  \nobreak\bigskip \nobreak
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak
 }
 \def\CHAPFopen{%
   \global\let\chapmacro=\chfopen
@@ -7856,7 +7807,7 @@
   \fi\fi
 }
 
-% 
+
 % @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
 % the node name, #2 the name of the Info cross-reference, #3 the printed
 % node name, #4 the name of the Info file, #5 the name of the printed
@@ -7866,21 +7817,16 @@
 \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
 \def\ref#1{\xrefX[#1,,,,,,,]}
 %
-\newbox\toprefbox
+\newbox\topbox
 \newbox\printedrefnamebox
-\newbox\infofilenamebox
 \newbox\printedmanualbox
 %
 \def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
   \unsepspaces
   %
-  % Get args without leading/trailing spaces.
   \def\printedrefname{\ignorespaces #3}%
   \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}%
   %
-  \def\infofilename{\ignorespaces #4}%
-  \setbox\infofilenamebox = \hbox{\infofilename\unskip}%
-  %
   \def\printedmanual{\ignorespaces #5}%
   \setbox\printedmanualbox  = \hbox{\printedmanual\unskip}%
   %
@@ -7915,18 +7861,11 @@
      \turnoffactive
      \makevalueexpandable
      % This expands tokens, so do it after making catcode changes, so _
-     % etc. don't get their TeX definitions.  This ignores all spaces in
-     % #4, including (wrongly) those in the middle of the filename.
+     % etc. don't get their TeX definitions.
      \getfilename{#4}%
      %
-     % This (wrongly) does not take account of leading or trailing
-     % spaces in #1, which should be ignored.
      \edef\pdfxrefdest{#1}%
-     \ifx\pdfxrefdest\empty
-       \def\pdfxrefdest{Top}% no empty targets
-     \else
-       \txiescapepdf\pdfxrefdest  % escape PDF special chars
-     \fi
+     \txiescapepdf\pdfxrefdest
      %
      \leavevmode
      \startlink attr{/Border [0 0 0]}%
@@ -7959,7 +7898,7 @@
       \printedrefname
     \fi
     %
-    % If the user also gave the printed manual name (fifth arg), append
+    % if the user also gave the printed manual name (fifth arg), append
     % "in MANUALNAME".
     \ifdim \wd\printedmanualbox > 0pt
       \space \putwordin{} \cite{\printedmanual}%
@@ -7974,20 +7913,32 @@
     % this is a loss.  Therefore, we give the text of the node name
     % again, so it is as if TeX is seeing it for the first time.
     % 
+    % Cross-manual reference.  Only include the "Section ``foo'' in" if
+    % the foo is neither missing or Top.  Thus, @xref{,,,foo,The Foo Manual}
+    % outputs simply "see The Foo Manual".
     \ifdim \wd\printedmanualbox > 0pt
-      % Cross-manual reference with a printed manual name.
+      % What is the 7sp about?  The idea is that we also want to omit
+      % the Section part if we would be printing "Top", since they are
+      % clearly trying to refer to the whole manual.  But, this being
+      % TeX, we can't easily compare strings while ignoring the possible
+      % spaces before and after in the input.  By adding the arbitrary
+      % 7sp, we make it much less likely that a real node name would
+      % happen to have the same width as "Top" (e.g., in a monospaced font).
+      % I hope it will never happen in practice.
       % 
-      \crossmanualxref{\cite{\printedmanual\unskip}}%
-    %
-    \else\ifdim \wd\infofilenamebox > 0pt
-      % Cross-manual reference with only an info filename (arg 4), no
-      % printed manual name (arg 5).  This is essentially the same as
-      % the case above; we output the filename, since we have nothing else.
+      % For the same basic reason, we retypeset the "Top" at every
+      % reference, since the current font is indeterminate.
       % 
-      \crossmanualxref{\code{\infofilename\unskip}}%
-    %
+      \setbox\topbox = \hbox{Top\kern7sp}%
+      \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
+      \ifdim \wd2 > 7sp
+        \ifdim \wd2 = \wd\topbox \else
+          \putwordSection{} ``\printedrefname'' \putwordin{}\space
+        \fi
+      \fi
+      \cite{\printedmanual}%
     \else
-      % Reference within this manual.
+      % Reference in this manual.
       %
       % _ (for example) has to be the character _ for the purposes of the
       % control sequence corresponding to the node, but it has to expand
@@ -8008,37 +7959,11 @@
       %
       % output the `page 3'.
       \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
-    \fi\fi
+    \fi
   \fi
   \endlink
 \endgroup}
 
-% Output a cross-manual xref to #1.  Used just above (twice).
-% 
-% Only include the text "Section ``foo'' in" if the foo is neither
-% missing or Top.  Thus, @xref{,,,foo,The Foo Manual} outputs simply
-% "see The Foo Manual", the idea being to refer to the whole manual.
-% 
-% But, this being TeX, we can't easily compare our node name against the
-% string "Top" while ignoring the possible spaces before and after in
-% the input.  By adding the arbitrary 7sp below, we make it much less
-% likely that a real node name would have the same width as "Top" (e.g.,
-% in a monospaced font).  Hopefully it will never happen in practice.
-% 
-% For the same basic reason, we retypeset the "Top" at every
-% reference, since the current font is indeterminate.
-% 
-\def\crossmanualxref#1{%
-  \setbox\toprefbox = \hbox{Top\kern7sp}%
-  \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}%
-  \ifdim \wd2 > 7sp  % nonempty?
-    \ifdim \wd2 = \wd\toprefbox \else  % same as Top?
-      \putwordSection{} ``\printedrefname'' \putwordin{}\space
-    \fi
-  \fi
-  #1%
-}
-
 % This macro is called from \xrefX for the `[nodename]' part of xref
 % output.  It's a separate macro only so it can be changed more easily,
 % since square brackets don't work well in some documents.  Particularly
Index: doc/libmicrohttpd.texi
===================================================================
--- doc/libmicrohttpd.texi	(revision 26980)
+++ doc/libmicrohttpd.texi	(working copy)
@@ -1086,6 +1086,25 @@
 @end deftypefun
 
 
+@deftypefun int MHD_quiesce_daemon (struct MHD_Daemon *daemon)
+Stop accepting connections from the listening socket.  Allows clients
+to continue processing, but stops accepting new connections.  Note
+that the caller is responsible for closing the returned socket;
+however, if MHD is run using threads (anything but external select
+mode), it must not be closed until AFTER @code{MHD_stop_daemon} has
+been called (as it is theoretically possible that an existing thread
+is still using it).
+
+This function is useful in the special case that a listen socket
+is to be migrated to another process (i.e. a newer version of the
+HTTP server) while existing connections should continue to be 
+processed until they are finished.
+
+Return @code{-1} on error (daemon not listening), the handle to the
+listen socket otherwise.
+@end deftypefun
+
+
 @deftypefun void MHD_stop_daemon (struct MHD_Daemon *daemon)
 Shutdown an HTTP daemon.
 @end deftypefun
Index: src/daemon/daemon.c
===================================================================
--- src/daemon/daemon.c	(revision 26980)
+++ src/daemon/daemon.c	(working copy)
@@ -660,7 +660,7 @@
 #ifdef HAVE_POLL_H
       else
 	{
-	    /* use poll */
+	  /* use poll */
 	  memset(&mp, 0, sizeof (struct MHD_Pollfd));
 	  MHD_connection_get_pollfd(con, &mp);
 	  memset(&p, 0, sizeof (p));
@@ -1137,11 +1137,14 @@
   int s;
   int flags;
   int need_fcntl;
+  int fd;
 
   addrlen = sizeof (addrstorage);
   memset (addr, 0, sizeof (addrstorage));
+  if (-1 == (fd = daemon->socket_fd))
+    return MHD_NO;
 #if HAVE_ACCEPT4
-  s = accept4 (daemon->socket_fd, addr, &addrlen, SOCK_CLOEXEC);
+  s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC);
   need_fcntl = MHD_NO;
 #else
   s = -1;
@@ -1149,7 +1152,7 @@
 #endif
   if (-1 == s)
   {
-    s = ACCEPT (daemon->socket_fd, addr, &addrlen);
+    s = ACCEPT (fd, addr, &addrlen);
     need_fcntl = MHD_YES;
   }
   if ((-1 == s) || (addrlen <= 0))
@@ -1353,6 +1356,7 @@
 		     const fd_set *except_fd_set)
 {
   int ds;
+  int tmp;
   struct MHD_Connection *pos;
   struct MHD_Connection *next;
 
@@ -1360,6 +1364,11 @@
   if ( (-1 != (ds = daemon->socket_fd)) &&
        (FD_ISSET (ds, read_fd_set)) )
     MHD_accept_connection (daemon);
+  /* drain signaling pipe to avoid spinning select */
+  if ( (-1 != daemon->wpipe[0]) &&
+       (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
+    (void) read (daemon->wpipe[0], &tmp, sizeof (tmp));
+
   if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
     {
       /* do not have a thread per connection, process all connections now */
@@ -1753,6 +1762,34 @@
 
 
 /**
+ * Stop accepting connections from the listening socket.  Allows
+ * clients to continue processing, but stops accepting new
+ * connections.  Note that the caller is responsible for closing the
+ * returned socket; however, if MHD is run using threads (anything but
+ * external select mode), it must not be closed until AFTER
+ * "MHD_stop_daemon" has been called (as it is theoretically possible
+ * that an existing thread is still using it).
+ *
+ * @param daemon daemon to stop accepting new connections for
+ * @return old listen socket on success, -1 if the daemon was 
+ *         already not listening anymore
+ */
+int
+MHD_quiesce_daemon (struct MHD_Daemon *daemon)
+{
+  unsigned int i;
+  int ret;
+
+  ret = daemon->socket_fd;
+  if (NULL != daemon->worker_pool)
+    for (i = 0; i < daemon->worker_pool_size; i++)        
+      daemon->worker_pool[i].socket_fd = -1;    
+  daemon->socket_fd = -1;
+  return ret;
+}
+
+
+/**
  * Signature of the MHD custom logger function.
  *
  * @param cls closure
@@ -2659,7 +2696,7 @@
   for (pos = daemon->connections_head; NULL != pos; pos = pos->next)    
     SHUTDOWN (pos->socket_fd, 
 	      (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);    
-  if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
+  if (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex))
     {
       MHD_PANIC ("Failed to release cleanup mutex\n");
     }
@@ -2729,8 +2766,9 @@
 #ifdef HAVE_LISTEN_SHUTDOWN
   else
     {
-      /* fd must not be -1 here, otherwise we'd have used the wpipe */
-      SHUTDOWN (fd, SHUT_RDWR);
+      /* fd might be -1 here due to 'MHD_quiesce_daemon' */
+      if (-1 != fd)
+	(void) SHUTDOWN (fd, SHUT_RDWR);
     }
 #endif
 #if DEBUG_CLOSE
@@ -2770,7 +2808,7 @@
     }
   close_all_connections (daemon);
   if (-1 != fd)
-    CLOSE (fd);
+    (void) CLOSE (fd);
 
   /* TLS clean up */
 #if HTTPS_SUPPORT
@@ -2791,10 +2829,9 @@
 
   if (-1 != daemon->wpipe[1])
     {
-      CLOSE (daemon->wpipe[0]);
-      CLOSE (daemon->wpipe[1]);
+      (void) CLOSE (daemon->wpipe[0]);
+      (void) CLOSE (daemon->wpipe[1]);
     }
-
   free (daemon);
 }
 
Index: src/daemon/EXPORT.sym
===================================================================
--- src/daemon/EXPORT.sym	(revision 26980)
+++ src/daemon/EXPORT.sym	(working copy)
@@ -22,6 +22,7 @@
 MHD_get_response_header
 MHD_create_post_processor
 MHD_post_process
+MHD_quiesce_daemon
 MHD_destroy_post_processor
 MHD_get_daemon_info
 MHD_get_connection_info
Index: src/include/microhttpd.h
===================================================================
--- src/include/microhttpd.h	(revision 26980)
+++ src/include/microhttpd.h	(working copy)
@@ -1102,6 +1102,23 @@
 
 
 /**
+ * Stop accepting connections from the listening socket.  Allows
+ * clients to continue processing, but stops accepting new
+ * connections.  Note that the caller is responsible for closing the
+ * returned socket; however, if MHD is run using threads (anything but
+ * external select mode), it must not be closed until AFTER
+ * "MHD_stop_daemon" has been called (as it is theoretically possible
+ * that an existing thread is still using it).
+ *
+ * @param daemon daemon to stop accepting new connections for
+ * @return old listen socket on success, -1 if the daemon was 
+ *         already not listening anymore
+ */
+int
+MHD_quiesce_daemon (struct MHD_Daemon *daemon);
+
+
+/**
  * Shutdown an http daemon.
  *
  * @param daemon daemon to stop
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26980)
+++ ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+Thu Apr 25 13:08:10 CEST 2013
+	Added 'MHD_quiesce_daemon' to allow application to stop
+	processing new incoming connections while finishing
+	ongoing requests. -CG
+
 Sun Mar 31 23:17:13 CEST 2013
 	Added MHD demonstration code 'src/examples/demo.c'. -CG
 

Reply via email to