Ugh. Kudos to Greg for getting me to look at a truss/strace of httpd, but I didn't find anything good to report...

On FreeBSD, it turns out we are being quite wasteful. It seems in all cases when we are writing to the client, our socket is always non-blocking, and therefore sendfile returns EAGAIN:

sendfile(0xf,0xe,0x0,0x0,0xedb4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0x8000,0x0,0x6db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0x9000,0x0,0x5db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0xa000,0x0,0x4db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0xb000,0x0,0x3db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0xc000,0x0,0x2db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0xd000,0x0,0x1db4,0xbfbfc5b0,0xbfbfc5a8,0x0) ERR#35 'Resource temporarily unavailable'
poll({14 0x0|IN|PRI|ERR|HUP|NVAL|RDNORM|RDBAND|WRBAND },1,300000) = 1 (0x1)
sendfile(0xf,0xe,0xe000,0x0,0xdb4,0xbfbfc5b0,0xbfbfc5a8,0x0) = 0 (0x0)
read(0xe,0x8173028,0x1f40) ERR#35 'Resource temporarily unavailable'
write(8,0x81730f0,77)                            = 77 (0x4d)
close(15)                                        = 0 (0x0)


8 calls to sendfile and poll to send a single 55K file. Ick.

I thought we were always supposed to be using a blocking socket when doing the sendfile?

Index: core_filters.c
===================================================================
--- core_filters.c      (revision 201576)
+++ core_filters.c      (working copy)
@@ -845,6 +845,8 @@
            return APR_SUCCESS;
        }

+        apr_socket_opt_set(net->client_socket, APR_SO_NONBLOCK, 0);
+
        if (fd) {
            apr_hdtr_t hdtr;
            apr_size_t bytes_sent;

After adding this patch, truss looks like:
fcntl(14,F_GETFL,0x10)                           = 6 (0x6)
fcntl(14,F_SETFL,0x2)                            = 0 (0x0)
sendfile(0xf,0xe,0x0,0x0,0xedb4,0xbfbfc5b0,0xbfbfc5a8,0x0) = 0 (0x0)
read(0xe,0x8173028,0x1f40)                       = 355 (0x163)
write(8,0x81750f0,77)                            = 77 (0x4d)
close(15)                                        = 0 (0x0)

Is our code for detection of inheriting non-blocking from the listening socket broken?

-Paul

Reply via email to