There are many places in AOLserver (anything that calls Ns_ConnReadLine
amongst others), that call down into the connection read procedure
requesting one byte. (Ns_ConnReadLine does this to make sure it reads only
to the end of line and can pass the rest of the data to the next proc...)
In AOLserver 3.0, nssock's sockread would faithfully read that just one byte.
In AOLserver 3.2 (maybe 3.1), sockread was changed to always read as much
as it could into each nssock connection's buffer, regardless of how much
the caller wants to get back. Presumably this speeds things up. It's the
same in AOLserver 3.3 and 3.4.
(For those playing the home game, the data is stored in nssock/ConnData.buf
and the count of the buffer is nssock/ConnData.cnt)
Enter nsvhr and nsunix.
The goals of nsvhr/nsunix is to reduce copying to a minimum. Read just
enough of a request to determine which proxy to pass the request too and
then pass what has been read and the original socket to that proxy.
When nsvhr finds it's making an nsunix style connection it passes data to
the nsunix proxy with two connections:
1. Connection One is a Unix domain socket that contains:
a) The request as read in so far,
b) The passed in socket descriptor of the client browser
2. Connection Two is the passed in socket descriptor.
The nsunix proxy reads as much as it can out of connection one, and then
switches to using connection two for the rest of its communications. For a
small GET, this mainly means that reads come from connection one, and
writes go out connection two. For a large POST, this means that reads come
from connections one and two, and writes go out connection two.
The problem is the data that is stored in the nssock connection's buffer is
not accessible to nsvhr. It's not accessible to anything except for
nssock. Nsvhr recreates the complete request by using the publically
accessible connection structures: header sets, request, etc. But since
nsvhr can't get to the connection's input buffer it can't put that data
into the request.
Oops.
For AOLserver 3.2, I removed the optimization from nssock/sockread and had
it continue to read only what was requested and no more, eliminating the
internal buffer. That worked fine, but presumably resulted in a
performance hit.
I have two sets of questions:
1. What are the performance aspects of just reading that one byte at a
time in sockread? Is it as bad as it seems or are there other buffers
already associated with the socket? Are we talking eliminating lots of
context switches, or are modern systems smarter than that?
2. What could nsvhr do (legitimately) to determine what's in the nssock
connection buffer? How can nsvhr read out what's in the buffer without
making nssock read more?
I have a really ugly solution that works. But it breaks the modularity of
the system, and it restricts nsvhr to using only nssock inputs, so I would
very much like to know what you folks recommend.
My solution (and I truly hesitate to admit this in public), is to change
nssock/sockread so that IF the input length is -1, then the count of bytes
in the connection buffer is returned as a negative number. In general what
can be done to optimize the reads and not require massive hacks all over
AOLserver?
Thanks,
Jerry
=====================================================
Jerry Asher [EMAIL PROTECTED]
1678 Shattuck Avenue Suite 161 Tel: (510) 549-2980
Berkeley, CA 94709 Fax: (877) 311-8688