httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Trawick <traw...@ibm.net>
Subject Re: [PATCH] ap_sendfile on Linux gets EINVAL
Date Mon, 17 Jul 2000 14:27:32 GMT
> Sender: greg@raleigh.ibm.com

That header doesn't look right :)

> Date: Fri, 14 Jul 2000 16:01:08 -0400
> From: Greg Ames <gregames@raleigh.ibm.com>
> 
> Index: lib/apr/network_io/unix/sendrecv.c
> ===================================================================
> RCS file: /cvs/apache/apache-2.0/src/lib/apr/network_io/unix/sendrecv.c,v
> retrieving revision 1.32
> diff -u -d -b -r1.32 sendrecv.c
> --- sendrecv.c  2000/07/07 03:00:44     1.32
> +++ sendrecv.c  2000/07/14 19:22:01
> @@ -212,29 +212,75 @@
>    */
>  
>  #if defined(__linux__) && defined(HAVE_WRITEV)
> +
> +/* TCP_CORK keeps us from sending partial frames when we shouldn't 
> + * however, it is mutually exclusive w/TCP_NODELAY  
> + */
> +
> +static int os_cork(ap_socket_t *sock)
> +{
> +    /* Linux only for now */
> +
> +    int nodelay_off = 0, corkflag = 1, rv, delayflag;
> +    socklen_t delaylen;
> +
> +    /* XXX it would be cheaper to use an ap_socket_t flag here */

You must set delaylen to sizeof delayflag before this call.  You've
been getting lucky so far with the accidental values in autodata (>= 4
will work fine in practice).

> +    rv = getsockopt(sock->socketdes, SOL_TCP, TCP_NODELAY,
> +                    (void *) &delayflag, &delaylen);
> +    if (rv == 0) {  
> +
> +        if (delayflag != 0) {
> +            /* turn off nodelay temporarily to allow cork */
> +            rv = setsockopt(sock->socketdes, SOL_TCP, TCP_NODELAY,
> +                            (const void *) &nodelay_off, sizeof(nodelay_off));
> +            if (rv < 0) {
> +                return rv;    
> +            }   
> +        } 
> +    }
> +    rv = setsockopt(sock->socketdes, SOL_TCP, TCP_CORK,
> +                    (const void *) &corkflag, sizeof(corkflag));

If this fails, why do we give a !@#$ beyond avoiding the uncork call?

> +    return rv == 0 ? delayflag : rv;
> +}   
> +
> +static int os_uncork(ap_socket_t *sock, int delayflag)
> +{
> +    /* Uncork to send queued frames - Linux only for now */
> +    
> +    int corkflag = 0, rv;
> +    rv = setsockopt(sock->socketdes, SOL_TCP, TCP_CORK,
> +                    (const void *) &corkflag, sizeof(corkflag));
> +    if (rv == 0) {
> +    
> +        /* restore TCP_NODELAY to its original setting */

What if you didn't have to change TCP_NODELAY to begin with (i.e.,
original setting was off)?  Don't turn it off again.

> +        rv = setsockopt(sock->socketdes, SOL_TCP, TCP_NODELAY,
> +                    (const void *) &delayflag, sizeof(delayflag));
> +        }
> +    return rv;
> +}
> +

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

Mime
View raw message