I'm kind of confused by some of the C code underlying of ns_write.
The comments for Ns_ConnWrite (in nsd/conn.c) and Ns_SockSend (in
nsd/sock.c) warn that each "may not write all the data you send it!"
And to prevent that problem, Ns_WriteConn and NsWriteConnRaw keep
calling Ns_ConnWrite until the count of the bytes written reaches the
length of the buffer to write.

But, why is that byte counting necessary?  Is because if the socket is
nonblockng it could return EWOULDBLOCK?  Is there any other reason?

And, when does Ns_SockSend return?  When the socket driver receives
acknowledgement that the client has received the data?  Or when the
the socket has the data buffered up and ready to go to the client?  If
the former, would it make sense and be usefull to have a version
simply hands a load of data to the tcp/ip stack and returns?  Or is
that not possible?

Ns_SockSend is pretty simple, its only complication at all is that it
seems to catch EWOULDBLOCK and call Ns_SockSend to wait until the send
buffer is again free, and then call send again.  But, it's not calling
send in a loop so presumably it could get EWOULDBLOCK again.

Why is it done that way?  Was the intention here to make Ns_SockSend
always block and behave identically regardless of whether the
underlying socket is blocking or nonblocking?  From the
implementation, I think NOT, but just what is the exact intention
there?  Am I misunderstanding something here?  Here's the code:

int
Ns_SockSend(SOCKET sock, void *buf, int towrite, int timeout)
{
    int nwrote;

    nwrote = send(sock, buf, towrite, 0);
    if (nwrote == -1
        && ns_sockerrno == EWOULDBLOCK
        && Ns_SockWait(sock, NS_SOCK_WRITE, timeout) == NS_OK) {
        nwrote = send(sock, buf, towrite, 0);
    }
    return nwrote;
}

--
Andrew Piskorski <[EMAIL PROTECTED]>
http://www.piskorski.com

Reply via email to