apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <gst...@lyra.org>
Subject Re: cvs commit: apr/network_io/unix sendrecv.c
Date Fri, 22 Dec 2000 01:26:37 GMT
Rather than waiting for IO to be possible, doesn't the sendfile() return the
number of bytes written? In other words, you would get EAGAIN *and* bytes
written. Thus, you know not to send that data again.

Seems like that would save a syscall for calls with timeout > 0.

Cheers,
-g

On Fri, Dec 22, 2000 at 12:19:17AM -0000, rbb@locus.apache.org wrote:
> rbb         00/12/21 16:19:17
> 
>   Modified:    .        CHANGES
>                network_io/unix sendrecv.c
>   Log:
>   On FreeBSD, it is possible for the first call to sendfile to
>   get EAGAIN, but still send some data.  This means that we cannot
>   call sendfile and then check for EAGAIN, and then wait and call
>   sendfile again.  If we do that, then we are likely to send the
>   first chunk of data twice, once in the first call and once in the
>   second.  If we are using a timed write, then we check to make sure
>   we can send data before trying to send it.  This gets sendfile working
>   on FreeBSD in Apache again.
>   
>   Revision  Changes    Path
>   1.30      +8 -0      apr/CHANGES
>   
>   Index: CHANGES
>   ===================================================================
>   RCS file: /home/cvs/apr/CHANGES,v
>   retrieving revision 1.29
>   retrieving revision 1.30
>   diff -u -r1.29 -r1.30
>   --- CHANGES	2000/12/22 00:02:49	1.29
>   +++ CHANGES	2000/12/22 00:19:14	1.30
>   @@ -1,5 +1,13 @@
>    Changes with APR b1
>    
>   +  *) On FreeBSD, it is possible for the first call to sendfile to
>   +     get EAGAIN, but still send some data.  This means that we cannot
>   +     call sendfile and then check for EAGAIN, and then wait and call
>   +     sendfile again.  If we do that, then we are likely to send the
>   +     first chunk of data twice, once in the first call and once in the
>   +     second.  If we are using a timed write, then we check to make sure
>   +     we can send data before trying to send it. [Ryan Bloom]
>   +
>      *) Cleanup to help Apache support programs build cleanly.
>         [Cliff Woolley <cliffwoolley@yahoo.com>]
>    
>   
>   
>   
>   1.52      +15 -22    apr/network_io/unix/sendrecv.c
>   
>   Index: sendrecv.c
>   ===================================================================
>   RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
>   retrieving revision 1.51
>   retrieving revision 1.52
>   diff -u -r1.51 -r1.52
>   --- sendrecv.c	2000/11/17 04:19:18	1.51
>   +++ sendrecv.c	2000/12/22 00:19:16	1.52
>   @@ -412,6 +412,21 @@
>        headerstruct.trl_cnt = hdtr->numtrailers;
>    
>        /* FreeBSD can send the headers/footers as part of the system call */
>   +    if (sock->timeout > 0) {
>   +        /* On FreeBSD, it is possible for the first call to sendfile to
>   +         * get EAGAIN, but still send some data.  This means that we cannot
>   +         * call sendfile and then check for EAGAIN, and then wait and call
>   +         * sendfile again.  If we do that, then we are likely to send the
>   +         * first chunk of data twice, once in the first call and once in the
>   +         * second.  If we are using a timed write, then we check to make sure
>   +         * we can send data before trying to send it.
>   +         */
>   +        apr_status_t arv = wait_for_io_or_timeout(sock, 0);
>   +        if (arv != APR_SUCCESS) {
>   +            *len = 0;
>   +            return arv;
>   +        }
>   +    }
>    
>        do {
>            if (bytes_to_send) {
>   @@ -442,28 +457,6 @@
>                }
>            }
>        } while (rv == -1 && errno == EINTR);
>   -
>   -    if (rv == -1 && 
>   -        (errno == EAGAIN || errno == EWOULDBLOCK) && 
>   -        sock->timeout > 0) {
>   -	apr_status_t arv = wait_for_io_or_timeout(sock, 0);
>   -	if (arv != APR_SUCCESS) {
>   -	    *len = 0;
>   -	    return arv;
>   -	}
>   -        else {
>   -            do {
>   -        	rv = sendfile(file->filedes,	/* open file descriptor of the file to be
sent */
>   -        		      sock->socketdes,	/* socket */
>   -        		      *offset,	/* where in the file to start */
>   -        		      (size_t) * len,	/* number of bytes to send */
>   -        		      &headerstruct,	/* Headers/footers */
>   -        		      &nbytes,	/* number of bytes written */
>   -        		      flags	/* undefined, set to 0 */
>   -        	    );
>   -            } while (rv == -1 && errno == EINTR);
>   -        }
>   -    }
>    
>        (*len) = nbytes;
>        if (rv == -1) {
>   
>   
>   

-- 
Greg Stein, http://www.lyra.org/

Mime
View raw message