From: Gustaf Neumann <neumann@wu...> - 2013-01-18 11:45:44
I just committed a larger change to naviserver tip for handling partial
(write operations that could not be completed in one go from the OS kernel,
sending just a portion of the requested size).
Previously, NsDriverSend() never performed partial writes although
some client functions handled it (not always correctly). The reason
for this was that nssock.sendProc used Ns_SockSendBufs() as
implementation, and Ns_SockSendBufs() uses its own timeouts and event
handling to deliver all content also on non-blocking sockets.
The consequence was, that every write request in the writer thread
waited until the full completion, which causes essentially a single
outgoing request per writer thread at a time. This problem was reduced
somewhat by the fact that file-spools read always smallish junks where
the blocking was usually not so long. The problem was especially bad
when fastpath-mmap + writer threads were activated and/or when only
one writer thread was defined. For file with sizes > writersize, this
meant sequentialization of file deliveries.
The complete-delivery scheme is not a problem, when the connection
threads send the content to the client (since multiple connection
threads can send back multiple streams and do not block each other
directly), but this is is a problem when e.g. a single writer thread
should deliver content of multiple requests.
Now, the new code handles partial low-level writes correctly by
allowing partial writes on the driver level. This requires some
reshuffling of the functions.
- The old SockSend() is now implementation of nssock.sendProc
and performs partial writes on non-blocking sockets.
- Ns_SockSendBufs() delivers all iovec bufs like before but calls
now NsDriverSend() instead of the direct SockSend().
- Ns_ConnSend() calls Ns_SockSendBufs() instead of NsDriverSend() in
cases, where the writer thread is not used.
- Ns_SockSendBufs() calls NsDriverSend() instead of SockSend()
- Ns_SockSendFileBufs() calls NsDriverSend() instead of
- Group fields in WriterSock to separate concern of file-spooling and
memory based requests.
- Factor out WriterSend() from DriverThread() to improve readability
The code was tested with nssock + nsssl on Mac OS X and Linux,
and is running on http://next-scripting.org
all the best