Hi,
End of May 2003, i submitted bug 20382
(http://nagoya.apache.org/bugzilla/show_bug.cgi?id=20382) which describes an
issue with Apache on Windows2000 Advanced Server performing very poorly in
some tested configurations. I also attached a proposed patch (which i'm sure
can be improved upon, but at least shows a resolution and perhaps a more
clear view of what's going on). According to
http://apr.apache.org/patches.html i should just ask again if it was ignored
for a longer while.
The issues seems to be that when sending a file in multiple-pieces using
SendFile() on Windows AS, the performance drops significantly, where as IIS
performance is very well, ruling out any network problems. Because the same
Apache configuration works fine on Windows2000 Professional, it also rules
out any configuration errors on the Apache side of things.
Above patch uses the TransmitFile() function to send the whole file at once,
instead of in 64kbyte blocks as the original program seems to do.
Thanks,
Maarten Bekers.
--- sendrecv.c Sat May 31 14:17:10 2003
+++ \sendrecv.c Mon Jan 6 16:52:56 2003
@@ -71,7 +71,7 @@
* For example, Apache will in most cases call apr_socket_send() with less
* than 8193 bytes.
*/
-#define MAX_SEGMENT_SIZE 0 /* set to a non-zero value to send the file in
smaller blocks */
+#define MAX_SEGMENT_SIZE 65536
#define WSABUF_ON_STACK 50
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
@@ -85,7 +85,6 @@
wsaData.len = *len;
wsaData.buf = (char*) buf;
-
#ifndef _WIN32_WCE
rv = WSASend(sock->socketdes, &wsaData, 1, &dwBytes, 0, NULL, NULL);
#else
@@ -115,7 +114,6 @@
wsaData.len = *len;
wsaData.buf = (char*) buf;
-
#ifndef _WIN32_WCE
rv = WSARecv(sock->socketdes, &wsaData, 1, &dwBytes, &flags, NULL, NULL);
#else
@@ -342,31 +340,9 @@
}
}
-
- /* if we are going to send the whole file at once */
- /* make sure the trailers are sent at the end */
- if (!MAX_SEGMENT_SIZE) {
- /* send all at once */
- nbytes = 0;
-
- /* ensure the trailers are sent at the end of the loop */
- sendv_trailers = 1;
- }
-
-
-
while (bytes_to_send) {
-
if (bytes_to_send > MAX_SEGMENT_SIZE) {
-
- /* if we dont want a transmit all, limit to this
maximum size */
- /* as defined by MAX_SEGMENT_SIZE */
- if (MAX_SEGMENT_SIZE)
- {
- nbytes = MAX_SEGMENT_SIZE;
-
- }
-
+ nbytes = MAX_SEGMENT_SIZE;
}
else {
/* Last call to TransmitFile() */
@@ -383,8 +359,6 @@
sendv_trailers = 1;
}
}
-
-
/* Disconnect the socket after last send */
if ((flags & APR_SENDFILE_DISCONNECT_SOCKET)
&& !sendv_trailers) {
@@ -462,26 +436,10 @@
if (status == APR_SUCCESS) {
if (sendv_trailers) {
- if (hdtr && hdtr->numtrailers) {
- if (!MAX_SEGMENT_SIZE) {
- /* got instructions to sent everything
at once */
- /* trailer collapsion never occured,
force it here */
-
-
- /* Collapse the trailers into a single
buffer */
- ptfb = &tfb;
- rv = collapse_iovec((char**)
&ptfb->Tail, &ptfb->TailLength,
-
hdtr->trailers, hdtr->numtrailers,
-
hdtrbuf + ptfb->HeadLength,
-
sizeof(hdtrbuf) - ptfb->HeadLength);
- }
-
-
- rv = apr_sendv(sock, hdtr->trailers, hdtr->numtrailers,
&nbytes);
- if (rv != APR_SUCCESS)
- return rv;
- *len += nbytes;
- }
+ rv = apr_sendv(sock, hdtr->trailers, hdtr->numtrailers, &nbytes);
+ if (rv != APR_SUCCESS)
+ return rv;
+ *len += nbytes;
}