Allan Edwards wrote:
> Anyone know why APR_TCP_NODELAY_INHERITED is not defined in apr.hw?
>
> Or why ap_sock_disable_nagle is not defined for Windows (looks
> like this was omitted unintentionally).
>
> Windows is exhibiting predicatable performance problems
> because nagle is enabled. The following patch fixes it.
>
> Also, it's not part of the nagle problem but it looks to me
> like APR_O_NONBLOCK_INHERITED was inadvertently left out of
> apr.hw also.
I. socket option optimization settings in APR
I've seen a few responses but nobody is stating clearly the condition
that allows either of these symbols to be set to 1. Can somebody fill
in the blanks?
On all Win32 socket layers, when you enable APR_TCP_NODELAY on a
listening socket that setting ___________ ("WILL" or "WILL NOT") then be
enabled automatically for associated connected sockets.
On all Win32 socket layers, when you enable APR_SO_NOBLOCK on a
listening socket that setting _____________ ("WILL" or "WILL NOT") then
be enabled automatically for associated connected sockets.
Neglecting to set these symbols to 1 when they could be will lead to an
almost immeasurable performance degradation. Setting them to 1 when
some Windows socket layers don't work that way it will break the
application.
II. ap_sock_disable_nagle() in Apache
(This discussion may seem somewhat orthogal to your concern about the
function not being compiled into the server for Win32, but I think that
if it works as I suggest below then we would be left with the extremely
minor performance question outlined above.)
As far as the ap_sock_disable_nagle() calls... That doesn't seem to be
implemented in the most clear manner. The calls Apache makes are
dependent on APR_TCP_NODELAY_INHERITED and
AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK. I would think that it should work
this way:
a) when setting up listening socket, unconditionally call
ap_sock_disable_nagle()
b) when setting up a newly-connected socket, unconditionally call
ap_sock_disable_nagle()
Very little extra overhead will be incurred since the APR setting of
APR_TCP_NODELAY_INHERITED will determine whether or not a syscall is
used when ap_sock_disable_nagle() calls
apr_socket_option_set(APR_TCP_NODELAY) on the newly-connected socket.
There is a comment from Bill somewhere about needing to leave this to
the MPM, but I think that until there is some MPM that doesn't want
Nagle disabled ever, APR should get to decide what exactly to do, and we
just make sure that Apache calls ap_sock_disable_nagle() when listening
sockets are initialized as well as when newly-connected sockets are
initialized.
I can only guess that the various MPMs that turn on
AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK in their corresponding mpm.h do so
because they expect that APR_TCP_NODELAY_INHERITED is always 1 on the
platforms where they run. Maybe that is true but it shouldn't be their
business to know so.
What to do about the platforms with no TCP_NODELAY? Always call the
function but
void ap_sock_disable_nagle(apr_socket_t *s)
{
#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF)
do_something();
#endif
}
Heck, Apache 2 doesn't even run on MPE or TPF.