perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <>
Subject Solution to apr stdio/msvc crt/service handles and logging
Date Thu, 27 Sep 2007 05:49:29 GMT
Presented in two parts, the first;

contains several changes that I believe will help the modperl community,
the mod_fcgid folks and virtually anyone attempting to do handle mashups
of different posix based engines on Win32.

In the previous fixes to APR 1.2.11, we stopped setting unused pipes
(where some were used) to the INVALID_HANDLE value.  We started in 1.2.11
to replicate stdin/out/err, where set to APR_NO_PIPE, as the parent's
standard handles.  This conforms to the unix implementation.

If this affected only compiled modules, fine, we'll just ask users to
absorb that pain.  But in fact every fcgid-style binary is compiled on
assumptions on windows about these handles.  We need a way for any
mod_fcgid style server to permit all of these compiled apps to continue
with their assumption, while not disrupting the typical case of using
APR to ensure portability.

The patch permits a new value to apr_procattr_io_set for any of the
three pipe creation mechanisms.  APR_NO_PIPE continues the new 1.2.11
behavior and replicates the parent's stdin/out/err where it's used.
APR_NO_FILE is a special case for *windows* APR 1.2, and would become a
portable feature in APR 1.3.  In the unix case, the designated NO_FILE
handles would be closed after fork, before exec.  In the windows case,
they are not inherited, and the child process sees INVALID_HANDLE_VALUE.

Now your obvious questions, what happens if an APR_NO_FILE is seen by
an older binary of APR?  APR_NO_PIPE, it simply inherits the old handle,
which is the default unix behavior, and new-1.2.11 default win32 behavior.
I've checked each code path, and on all platforms this is true.  I picked
the value 8 just to keep it out of the way of any bitmask we might choose
to apply.  And of course, where's the unix implementation for 1.3?  Just
haven't gotten to it yet, it's trivial to implement and I'll hack that
up shortly after we decide if we are on the right track.


The second piece of this patch is trivial.  It's possible that a given
standard windows handle is either NULL, or INVALID_HANDLE_VALUE.  It was
impossible to apr_file_stderr_open() so it becomes impossible to then
apr_file_dup2(stdhandle, sourcehandle, pool) with out the apr_file_t of
stdhandle.  We coerce any NULL handle into an INVALID_HANDLE_VALUE and
add an internal ->flags tag corresponding to the stdXXX handle opened.
This lets us replace the std apr_file_t with no pain, no comparison to
the unassigned standard handle.


On the third piece of this patch, the calls to apr_file_dup2() become
MSVC-aware, and correctly wire up the plumbing of the CRT.  Now this is
still not going to solve every problem, because there are local artifacts
per-CRT version, and in an httpd server using one version for apr/httpd,
another for a compiled module, and perhaps another for the language linked
in (e.g. AS python or perl) these can become disjoint.  Regrettable, but
also unavoidable.

Since day 1, APR only contended with the Win32 API layer standard handles.
This patch changes that behavior, and I believe it has a direct impact on
the modperl module.  Since modperl is emitting noise of it's troubles into
the stderr (CRT-style) stream, we dumped that on the floor on Win32.  With
this patch, we should be able to capture emits from modules, libraries etc
which are filling the stderr stream with useful diagnostics.

We also need to consider the impact of the _O_BINARY flag, an atypical
win32 use.  But we don't want piped in/out/err to be subject to random
or malicious emits of ^Z and other strange side effects beyond \n handling.

The exciting news, modperl startup failures and syntax diagnostics will land
in the error log.


Continuing on to the second part;

Another third trouble for modperl and this patch was lurking in mpm_winnt
from the 2.2.6 release, and the apr patch above isn't sufficient.  I've
simplified the processing of stdin/stdout handling and nt_eventlog stderr
handling, based on these existing apr features.  One patch doesn't work
terribly well without the other, due to these cart-before-the-horse issues.

Also we held open the first piped logger by sharing it's fd with the
child process, since we hadn't torn down the stale plog pool before we
invoke the new logger.  This is by-design, but because there were two
copies of the fd the logger wouldn't go away.  Attached is the Rudgier's
proposed patch (as we were hacking away to the same solution at the same
time, but his comments are more filling).

We had been fixing up the Win32 STANDARD_INPUT to the \device\null channel
without the corresponding stdio pseudo-posix fix, and this caused pain to
modperl in particular.  Because APR is now used for all of these issues,
future issues will be solved hopefully with apr-specific fixes only.


That's it, long post, two modestly large (much of it triplicated :) patches
to be reviewed and tested out.  Please share feedback so we can get moving
towards apr 1.2.12 and httpd 2.2.7.  Steffan of ApacheLounge has pointed out
these sorts of semi-major behavioral changes, although they don't represent
an API bump, are worthy of an httpd minor MMN bump in any case, and I concur
with him for the 2.2.7 release.


View raw message