You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by je...@apache.org on 2001/07/24 05:02:58 UTC

cvs commit: apr/network_io/unix sendrecv.c

jerenkrantz    01/07/23 20:02:58

  Modified:    .        CHANGES configure.in
               network_io/unix sendrecv.c
  Log:
  Add Solaris 8 sendfilev() support.
  
  Passes the sendfile client/server test in apr.
  
  Tested on Solaris 8/Sparc with latest recommended patches and the patches
  as listed in:
  http://sunsolve.Sun.COM/pub-cgi/retrieve.pl?doc=fpatches%2F111297 (Sparc)
  http://sunsolve.Sun.COM/pub-cgi/retrieve.pl?doc=fpatches%2F111298 (x86)
  
  Revision  Changes    Path
  1.125     +4 -0      apr/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apr/CHANGES,v
  retrieving revision 1.124
  retrieving revision 1.125
  diff -u -r1.124 -r1.125
  --- CHANGES	2001/07/23 03:28:30	1.124
  +++ CHANGES	2001/07/24 03:02:58	1.125
  @@ -1,5 +1,9 @@
   Changes with APR b1  
   
  +  *) Add Solaris 8's sendfilev() support.  This requires the following 
  +     patches from Sun: 111297 (Sparc), 111298 (x86).  You'll need the
  +     other patches listed in the patch description.  [Justin Erenkrantz]
  +
     *) Close file descriptor when we are done with fcntl or flock-based
        cross-process lock.  Otherwise, we leak descriptors.
        [Justin Erenkrantz]
  
  
  
  1.342     +2 -1      apr/configure.in
  
  Index: configure.in
  ===================================================================
  RCS file: /home/cvs/apr/configure.in,v
  retrieving revision 1.341
  retrieving revision 1.342
  diff -u -r1.341 -r1.342
  --- configure.in	2001/07/23 12:30:52	1.341
  +++ configure.in	2001/07/24 03:02:58	1.342
  @@ -466,7 +466,8 @@
   AC_CHECK_FUNCS(getrlimit, [ have_getrlimit="1" ], [ have_getrlimit="0" ]) 
   AC_CHECK_FUNCS(writev)
   sendfile="0"
  -AC_CHECK_FUNCS(sendfile send_file, [ sendfile="1" ])
  +AC_CHECK_LIB(sendfile, sendfilev)
  +AC_CHECK_FUNCS(sendfile send_file sendfilev, [ sendfile="1" ])
   
   dnl THIS MUST COME AFTER THE THREAD TESTS - FreeBSD doesn't always have a
   dnl threaded poll() and we don't want to use sendfile on early FreeBSD 
  
  
  
  1.67      +87 -0     apr/network_io/unix/sendrecv.c
  
  Index: sendrecv.c
  ===================================================================
  RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
  retrieving revision 1.66
  retrieving revision 1.67
  diff -u -r1.66 -r1.67
  --- sendrecv.c	2001/07/10 15:01:37	1.66
  +++ sendrecv.c	2001/07/24 03:02:58	1.67
  @@ -742,6 +742,93 @@
    * we don't use it until it is fixed.  If it is used as it is now, it will
    * hang the machine and the only way to fix it is a reboot.
    */
  +#elif defined(HAVE_SENDFILEV)
  +/* Solaris 8's sendfilev() interface 
  + *
  + * SFV_FD_SELF refers to our memory space.
  + *
  + * Required Sparc patches (or newer):
  + * 111297-01, 108528-09, 109472-06, 109234-03, 108995-02, 111295-01, 109025-03,
  + * 108991-13
  + * Required x86 patches (or newer):
  + * 111298-01, 108529-09, 109473-06, 109235-04, 108996-02, 111296-01, 109026-04,
  + * 108992-13
  + */
  +apr_status_t apr_sendfile(apr_socket_t *sock, apr_file_t *file,
  +        		apr_hdtr_t *hdtr, apr_off_t *offset, apr_size_t *len,
  +        		apr_int32_t flags)
  +{
  +    apr_status_t rv;
  +    size_t nbytes;
  +    sendfilevec_t *sfv;
  +    int vecs, curvec, i;
  +
  +    if (!hdtr) {
  +        hdtr = &no_hdtr;
  +    }
  +
  +    /* Ignore flags for now. */
  +    flags = 0;
  +
  +    /* Calculate how much space we need. */
  +    vecs = hdtr->numheaders + hdtr->numtrailers + 1;
  +    sfv = apr_palloc(sock->cntxt, sizeof(sendfilevec_t) * vecs);
  +
  +    curvec = 0;
  +
  +    /* Add the headers */
  +    for (i = 0; i < hdtr->numheaders; i++, curvec++) {
  +        sfv[curvec].sfv_fd = SFV_FD_SELF;
  +        sfv[curvec].sfv_flag = 0;
  +        sfv[curvec].sfv_off = hdtr->headers[i].iov_base;
  +        sfv[curvec].sfv_len = hdtr->headers[i].iov_len;
  +    }
  +
  +    /* If the len is 0, we skip the file. */
  +    if (*len)
  +    {
  +        sfv[curvec].sfv_fd = file->filedes;
  +        sfv[curvec].sfv_flag = 0;
  +        sfv[curvec].sfv_off = *offset;
  +        sfv[curvec].sfv_len = *len; 
  +
  +        curvec++;
  +    }
  +    else
  +        vecs--;
  +
  +    /* Add the footers */
  +    for (i = 0; i < hdtr->numtrailers; i++, curvec++) {
  +        sfv[curvec].sfv_fd = SFV_FD_SELF;
  +        sfv[curvec].sfv_flag = 0;
  +        sfv[curvec].sfv_off = hdtr->trailers[i].iov_base;
  +        sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
  +    }
  + 
  +    /* If we are in non-blocking mode, we need to make sure we wait until
  +     * the other side says it is okay. */ 
  +    if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) == 1 ||
  +        apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
  +    { 
  +        rv = apr_wait_for_io_or_timeout(sock, 0);
  +    }
  +
  +    /* Actually do the sendfilev */
  +    do {
  +        /* socket, vecs, number of vecs, bytes written */
  +        rv = sendfilev(sock->socketdes,	sfv, vecs, &nbytes);
  +    } while (rv == -1 && errno == EINTR);
  +
  +    /* Solaris returns EAGAIN even though it sent bytes on a non-block sock */
  +    if (rv == -1 && errno != EAGAIN) {
  +        rv = errno;
  +        return rv;
  +    }
  +
  +    /* Update how much we sent */
  +    *len = nbytes;
  +    return APR_SUCCESS;
  +}
   #else
   #error APR has detected sendfile on your system, but nobody has written a
   #error version of it for APR yet.  To get past this, either write apr_sendfile
  
  
  

Re: cvs commit: apr/network_io/unix sendrecv.c

Posted by Jeff Trawick <tr...@attglobal.net>.
jerenkrantz@apache.org writes:

> jerenkrantz    01/07/23 20:02:58
> 
>   Modified:    .        CHANGES configure.in
>                network_io/unix sendrecv.c
>   Log:
>   Add Solaris 8 sendfilev() support.
>   
>   Index: sendrecv.c

>   +    /* If we are in non-blocking mode, we need to make sure we wait until
>   +     * the other side says it is okay. */ 
>   +    if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) == 1 ||
>   +        apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
>   +    { 
>   +        rv = apr_wait_for_io_or_timeout(sock, 0);
>   +    }

1) bug

   We shouldn't wait for writability when the app has set the APR
   nonblock option.  We only do that when the app has set the APR
   timeout option to non-zero.

2) performance...

   You should check for writability *after* sendfilev() returns
   EAGAIN.  Otherwise, we get extra syscalls from time to time.

   Yeah, rbb made the FreeBSD apr_sendfile() check for writability
   first, but it is preferable to call sendfilev() first *then* wait
   if needed.

   Since a web server will use sendfile() often on small files (e.g.,
   .png) you can bet that this will have a bunch of unnecessary
   select() calls.

>   +
>   +    /* Actually do the sendfilev */
>   +    do {
>   +        /* socket, vecs, number of vecs, bytes written */
>   +        rv = sendfilev(sock->socketdes,	sfv, vecs, &nbytes);
>   +    } while (rv == -1 && errno == EINTR);
>   +
>   +    /* Solaris returns EAGAIN even though it sent bytes on a non-block sock */
>   +    if (rv == -1 && errno != EAGAIN) {
>   +        rv = errno;
>   +        return rv;
>   +    }

-- 
Jeff Trawick | trawick@attglobal.net | PGP public key at web site:
       http://www.geocities.com/SiliconValley/Park/9289/
             Born in Roswell... married an alien...