You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2008/04/24 22:26:41 UTC
svn commit: r651398 - in /apr/apr/branches/1.3.x: CHANGES
network_io/unix/sendrecv.c
Author: wrowe
Date: Thu Apr 24 13:26:35 2008
New Revision: 651398
URL: http://svn.apache.org/viewvc?rev=651398&view=rev
Log:
Support OS/X sendfile by using writev rather than the miscounted sendfile's
hdtr iovecs.
Submitted by: Geoff Greer <angryparsley mipsisrisc.com>
Backports: r651395
Modified:
apr/apr/branches/1.3.x/CHANGES
apr/apr/branches/1.3.x/network_io/unix/sendrecv.c
Modified: apr/apr/branches/1.3.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/CHANGES?rev=651398&r1=651397&r2=651398&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/CHANGES [utf-8] (original)
+++ apr/apr/branches/1.3.x/CHANGES [utf-8] Thu Apr 24 13:26:35 2008
@@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes for APR 1.3.0
+ *) Support OS/X sendfile by using writev in lieu of hdtr vecs
+ miscounted by the OS. [Geoff Greer <angryparsley mipsisrisc.com>]
+
*) Implement apr_proc_wait_all_procs for windows.
The implementation uses tool help library present
on Windows 2000 and later. APR_ENOTIMPL is returned
Modified: apr/apr/branches/1.3.x/network_io/unix/sendrecv.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.3.x/network_io/unix/sendrecv.c?rev=651398&r1=651397&r2=651398&view=diff
==============================================================================
--- apr/apr/branches/1.3.x/network_io/unix/sendrecv.c (original)
+++ apr/apr/branches/1.3.x/network_io/unix/sendrecv.c Thu Apr 24 13:26:35 2008
@@ -411,8 +411,9 @@
apr_size_t * len, apr_int32_t flags)
{
apr_off_t nbytes = *len;
+ apr_off_t bytes_to_send = *len;
+ apr_size_t header_bytes_written = 0;
int rv;
- struct sf_hdtr headerstruct;
/* Ignore flags for now. */
flags = 0;
@@ -421,12 +422,10 @@
hdtr = &no_hdtr;
}
- headerstruct.headers = hdtr->headers;
- headerstruct.hdr_cnt = hdtr->numheaders;
- headerstruct.trailers = hdtr->trailers;
- headerstruct.trl_cnt = hdtr->numtrailers;
-
- /* BSD can send the headers/footers as part of the system call */
+ /* OS X can send the headers/footers as part of the system call,
+ * but how it counts bytes isn't documented properly. We use
+ * writev() instead.
+ */
do {
if (sock->options & APR_INCOMPLETE_WRITE) {
apr_status_t arv;
@@ -437,18 +436,33 @@
return arv;
}
}
- if (nbytes) {
+
+ if (hdtr->numheaders) {
+ rv = writev(sock->socketdes,
+ hdtr->headers,
+ hdtr->numheaders);
+ if (rv > 0) {
+ header_bytes_written = rv;
+ rv = 0;
+ }
+ else {
+ header_bytes_written = 0;
+ }
+ }
+ else if (bytes_to_send) {
/* We won't dare call sendfile() if we don't have
* header or file bytes to send because nbytes == 0
* means send the remaining file to EOF.
*/
+ nbytes = bytes_to_send;
rv = sendfile(file->filedes, /* file to be sent */
sock->socketdes, /* socket */
*offset, /* where in the file to start */
&nbytes, /* number of bytes to write/written */
- &headerstruct, /* Headers/footers */
+ NULL, /* Headers/footers */
flags); /* undefined, set to 0 */
+ bytes_to_send -= nbytes;
if (rv == -1) {
if (errno == EAGAIN) {
if (sock->timeout > 0) {
@@ -460,7 +474,7 @@
*/
if (nbytes) {
/* normal exit for a big file & non-blocking io */
- (*len) = nbytes;
+ (*len) = nbytes + header_bytes_written;
return APR_SUCCESS;
}
}
@@ -470,11 +484,11 @@
/* Most likely the file got smaller after the stat.
* Return an error so the caller can do the Right Thing.
*/
- (*len) = nbytes;
+ (*len) = nbytes + header_bytes_written;
return APR_EOF;
}
}
- }
+ }
else {
/* just trailer bytes... use writev()
*/