stoddard 2004/07/21 18:48:35
Modified: . CHANGES
include/arch/win32 apr_arch_networkio.h
network_io/win32 sendrecv.c sockets.c
Log:
Win32: Fix bug in apr_socket_sendfile that interferred with LSPs. PR 23982
Revision Changes Path
1.484 +2 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.483
retrieving revision 1.484
diff -u -r1.483 -r1.484
--- CHANGES 20 Jul 2004 03:31:57 -0000 1.483
+++ CHANGES 22 Jul 2004 01:48:34 -0000 1.484
@@ -1,4 +1,6 @@
Changes for APR 1.1 [Deferring these features when 1.0 is rolled out.]
+ *) Win32: Fix bug in apr_socket_sendfile that interferred with
+ Win32 LSPs. PR 23982 [Jan Bilek, Bill Stoddard]
*) Add a new PRNG. Note that the implementation of SHA-256 is a
stop-gap pending snarfing the SHA-1 implementation from apr-util
1.7 +5 -0 apr/include/arch/win32/apr_arch_networkio.h
Index: apr_arch_networkio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/apr_arch_networkio.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- apr_arch_networkio.h 13 Feb 2004 09:38:31 -0000 1.6
+++ apr_arch_networkio.h 22 Jul 2004 01:48:34 -0000 1.7
@@ -42,6 +42,11 @@
int remote_addr_unknown;
apr_int32_t options;
apr_int32_t inherit;
+ /* As of 07.20.04, the overlapped structure is only used by
+ * apr_socket_sendfile and that's where it will be allocated
+ * and initialized.
+ */
+ OVERLAPPED *overlapped;
sock_userdata_t *userdata;
/* if there is a timeout set, then this pollset is used */
1.67 +17 -30 apr/network_io/win32/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/win32/sendrecv.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- sendrecv.c 13 Feb 2004 09:38:33 -0000 1.66
+++ sendrecv.c 22 Jul 2004 01:48:34 -0000 1.67
@@ -206,16 +206,6 @@
#if APR_HAS_SENDFILE
/*
- *#define WAIT_FOR_EVENT
- * Note: Waiting for the socket directly is much faster than creating a
seperate
- * wait event. There are a couple of dangerous aspects to waiting directly
- * for the socket. First, we should not wait on the socket if concurrent
threads
- * can wait-on/signal the same socket. This shouldn't be happening with
Apache since
- * a socket is uniquely tied to a thread. This will change when we begin
using
- * async I/O with completion ports on the socket.
- */
-
-/*
* apr_status_t apr_socket_sendfile(apr_socket_t *, apr_file_t *, apr_hdtr_t
*,
* apr_off_t *, apr_size_t *, apr_int32_t
flags)
* Send a file from an open file descriptor to a socket, along with
@@ -239,13 +229,11 @@
apr_off_t curoff = *offset;
DWORD dwFlags = 0;
DWORD nbytes;
- OVERLAPPED overlapped;
TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL;
int ptr = 0;
int bytes_to_send; /* Bytes to send out of the file (not including
headers) */
int disconnected = 0;
int sendv_trailers = 0;
- HANDLE wait_event;
char hdtrbuf[4096];
if (apr_os_level < APR_WIN_NT) {
@@ -275,14 +263,7 @@
return APR_SUCCESS;
}
- /* Initialize the header/trailer and overlapped structures */
memset(&tfb, '\0', sizeof (tfb));
- memset(&overlapped,'\0', sizeof(overlapped));
-#ifdef WAIT_FOR_EVENT
- wait_event = overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-#else
- wait_event = (HANDLE) sock->socketdes;
-#endif
/* Collapse the headers into a single buffer */
if (hdtr && hdtr->numheaders) {
@@ -301,6 +282,12 @@
}
}
+ /* Initialize the overlapped structure used on TransmitFile
+ */
+ if (!sock->overlapped) {
+ sock->overlapped = apr_pcalloc(sock->cntxt, sizeof(OVERLAPPED));
+ sock->overlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ }
while (bytes_to_send) {
if (bytes_to_send > MAX_SEGMENT_SIZE) {
nbytes = MAX_SEGMENT_SIZE;
@@ -329,16 +316,16 @@
}
}
- overlapped.Offset = (DWORD)(curoff);
+ sock->overlapped->Offset = (DWORD)(curoff);
#if APR_HAS_LARGE_FILES
- overlapped.OffsetHigh = (DWORD)(curoff >> 32);
+ sock->overlapped->OffsetHigh = (DWORD)(curoff >> 32);
#endif
/* XXX BoundsChecker claims dwFlags must not be zero. */
rv = TransmitFile(sock->socketdes, /* socket */
file->filehand, /* open file descriptor of the
file to be sent */
nbytes, /* number of bytes to send. 0=send
all */
0, /* Number of bytes per send. 0=use
default */
- &overlapped, /* OVERLAPPED structure */
+ sock->overlapped, /* OVERLAPPED structure */
ptfb, /* header and trailer buffers */
dwFlags); /* flags to control various
aspects of TransmitFile */
if (!rv) {
@@ -346,17 +333,20 @@
if ((status == APR_FROM_OS_ERROR(ERROR_IO_PENDING)) ||
(status == APR_FROM_OS_ERROR(WSA_IO_PENDING)))
{
- rv = WaitForSingleObject(wait_event,
+ rv = WaitForSingleObject(sock->overlapped->hEvent,
(DWORD)(sock->timeout >= 0
? sock->timeout_ms :
INFINITE));
if (rv == WAIT_OBJECT_0) {
status = APR_SUCCESS;
if (!disconnected) {
- if (!GetOverlappedResult(wait_event, &overlapped,
- &nbytes, FALSE)) {
- status = apr_get_os_error();
+ if (!WSAGetOverlappedResult(sock->socketdes,
+ sock->overlapped,
+ &nbytes,
+ FALSE,
+ &dwFlags)) {
+ status = apr_get_netos_error();
}
- /* Ugly code alert: GetOverlappedResult returns
+ /* Ugly code alert: WSAGetOverlappedResult returns
* a count of all bytes sent. This loop only
* tracks bytes sent out of the file.
*/
@@ -415,9 +405,6 @@
}
}
-#ifdef WAIT_FOR_EVENT
- CloseHandle(overlapped.hEvent);
-#endif
return status;
}
1.106 +4 -0 apr/network_io/win32/sockets.c
Index: sockets.c
===================================================================
RCS file: /home/cvs/apr/network_io/win32/sockets.c,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -r1.105 -r1.106
--- sockets.c 21 May 2004 22:21:13 -0000 1.105
+++ sockets.c 22 Jul 2004 01:48:35 -0000 1.106
@@ -35,6 +35,10 @@
}
thesocket->socketdes = INVALID_SOCKET;
}
+ if (thesocket->overlapped) {
+ CloseHandle(thesocket->overlapped->hEvent);
+ thesocket->overlapped = NULL;
+ }
return APR_SUCCESS;
}