gregames 02/04/24 14:39:24
Modified: . CHANGES
network_io/unix sendrecv.c
Log:
apr_sendfile: implement APR_INCOMPLETE_WRITE semantics for FreeBSD. This
cuts the number of sendfile syscalls in half for big files.
Also, bail out early in the normal case to reduce i-cache pollution.
Revision Changes Path
1.266 +3 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.265
retrieving revision 1.266
diff -u -r1.265 -r1.266
--- CHANGES 22 Apr 2002 13:15:48 -0000 1.265
+++ CHANGES 24 Apr 2002 21:39:23 -0000 1.266
@@ -1,5 +1,8 @@
Changes with APR b1
+ *) Reduce the number of apr_sendfile calls on FreeBSD by remembering
+ when the kernel tells us the next one will block. [Greg Ames]
+
*) To support modules like PHP, which implement their own
loaded extensions, Darwin needs to place their public
symbols in the global table. [Marko Karppinen <[EMAIL PROTECTED]>,
1.81 +23 -11 apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- sendrecv.c 11 Apr 2002 03:15:47 -0000 1.80
+++ sendrecv.c 24 Apr 2002 21:39:24 -0000 1.81
@@ -456,6 +456,15 @@
/* FreeBSD can send the headers/footers as part of the system call */
do {
+ if (sock->netmask & APR_INCOMPLETE_WRITE) {
+ apr_status_t arv;
+ sock->netmask &= ~APR_INCOMPLETE_WRITE;
+ arv = apr_wait_for_io_or_timeout(sock, 0);
+ if (arv != APR_SUCCESS) {
+ *len = 0;
+ return arv;
+ }
+ }
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
@@ -468,18 +477,21 @@
&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;
+
+ if (rv == -1 && errno == EAGAIN) {
+ if (sock->timeout) {
+ sock->netmask |= APR_INCOMPLETE_WRITE;
+ }
+ /* 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 (nbytes) {
+ /* normal exit for a big file & non-blocking io */
+ (*len) = nbytes;
+ return APR_SUCCESS;
+ }
}
-
- /* ??? performance: if rv == 0 is the most common case,
- * we may want to return here and avoid a potential
- * i-cache miss.
- */
}
else {
/* just trailer bytes... use writev()