apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@apache.org
Subject cvs commit: apr/network_io/unix sendrecv.c
Date Wed, 25 Jul 2001 20:59:29 GMT
trawick     01/07/25 13:59:29

  Modified:    network_io/unix sendrecv.c
  Log:
  fix some issues with apr_sendfile() for FreeBSD
  
  1) checking when to call wait_for_io_or_timeout()
     it checked errno without checking rv
     it required that we already sent bytes (nbytes != 0)
     it checked timeout != 0 instead of timeout > 0
  2) it didn't retry the sendfile() (or writev()) after
     a successful wait_for_io_or_timeout()
  
  Revision  Changes    Path
  1.72      +41 -14    apr/network_io/unix/sendrecv.c
  
  Index: sendrecv.c
  ===================================================================
  RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
  retrieving revision 1.71
  retrieving revision 1.72
  diff -u -r1.71 -r1.72
  --- sendrecv.c	2001/07/25 05:27:32	1.71
  +++ sendrecv.c	2001/07/25 20:59:29	1.72
  @@ -447,24 +447,51 @@
           }
       } while (rv == -1 && errno == EINTR);
   
  -    /* On FreeBSD, it is possible that sendfile will return 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.
  -     *
  -     * When we are dealing with a non-blocking or timeout socket, the
  -     * caller must already be aware that we may not be able to write
  -     * everything in one call.  Therefore, we should return back to
  -     * the caller with how much we actually sent (as specified from EAGAIN).
  -     *
  -     * If we are using a timed write, we will now block until we are clear.
  -     */
  -    if (errno == EAGAIN && nbytes && sock->timeout >= 0) {
  +    if (rv == -1 &&
  +        errno == EAGAIN && 
  +        sock->timeout > 0) {
           apr_status_t arv = apr_wait_for_io_or_timeout(sock, 0);
           if (arv != APR_SUCCESS) {
               *len = 0;
               return arv;
  +        }
  +        else {
  +            do {
  +                if (bytes_to_send) {
  +                    /* We won't dare call sendfile() if we don't have
  +                     * header or file bytes to send because bytes_to_send == 0
  +                     * means send the whole file.
  +                     */
  +                    rv = sendfile(file->filedes, /* file to be sent */
  +                                  sock->socketdes, /* socket */
  +                                  *offset,       /* where in the file to start */
  +                                  bytes_to_send, /* number of bytes to send */
  +                                  &headerstruct, /* Headers/footers */
  +                                  &nbytes,       /* number of bytes written */
  +                                  flags);        /* undefined, set to 0 */
  +                    /* FreeBSD's sendfile can return -1/EAGAIN even if it
  +                     * sent bytes.  Sanitize the result so we get normal EAGAIN
  +                     * semantics w.r.t. bytes sent.
  +                     */
  +                    if (rv == -1 && errno == EAGAIN && nbytes) {
  +                        rv = 0;
  +                    }
  +                }
  +                else {
  +                    /* just trailer bytes... use writev()
  +                     */
  +                    rv = writev(sock->socketdes,
  +                                hdtr->trailers,
  +                                hdtr->numtrailers);
  +                    if (rv > 0) {
  +                        nbytes = rv;
  +                        rv = 0;
  +                    }
  +                    else {
  +                        nbytes = 0;
  +                    }
  +                }
  +            } while (rv == -1 && errno == EINTR);
           }
       }
   
  
  
  

Mime
View raw message