summaryrefslogtreecommitdiff
path: root/network_io
diff options
context:
space:
mode:
authorstoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68>2000-06-14 17:16:47 +0000
committerstoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68>2000-06-14 17:16:47 +0000
commit913b2ad191416d6122794a41ed8140b45c9a051e (patch)
tree3facdd31dfe69b1e0f7558bb1000d80019d3434d /network_io
parent08946f8304d224e2634801b5acda3615f53755cc (diff)
downloadlibapr-913b2ad191416d6122794a41ed8140b45c9a051e.tar.gz
Get non-blocking network I/O working on Windows. Apache serves pages on Windows
now. Cleaned up some Windows specific bugs with timing out connections as well. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@60202 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io')
-rw-r--r--network_io/win32/sockets.c7
-rw-r--r--network_io/win32/sockopt.c47
2 files changed, 42 insertions, 12 deletions
diff --git a/network_io/win32/sockets.c b/network_io/win32/sockets.c
index bfc229560..63c19b03a 100644
--- a/network_io/win32/sockets.c
+++ b/network_io/win32/sockets.c
@@ -97,11 +97,13 @@ ap_status_t ap_create_tcp_socket(ap_socket_t **new, ap_pool_t *cont)
}
(*new)->local_addr->sin_family = AF_INET;
+ (*new)->remote_addr->sin_family = AF_INET;
(*new)->addr_len = sizeof(*(*new)->local_addr);
(*new)->local_addr->sin_port = 0;
-
+
+ (*new)->timeout = -1;
ap_register_cleanup((*new)->cntxt, (void *)(*new),
socket_cleanup, ap_null_cleanup);
return APR_SUCCESS;
@@ -169,6 +171,7 @@ ap_status_t ap_accept(ap_socket_t **new, const ap_socket_t *sock, ap_pool_t *con
memcpy((*new)->local_addr, sock->local_addr, sizeof(struct sockaddr_in));
(*new)->addr_len = sizeof(struct sockaddr_in);
+ (*new)->timeout = -1;
(*new)->sock = accept(sock->sock, (struct sockaddr *)(*new)->local_addr,
&(*new)->addr_len);
@@ -176,7 +179,7 @@ ap_status_t ap_accept(ap_socket_t **new, const ap_socket_t *sock, ap_pool_t *con
if ((*new)->sock == INVALID_SOCKET) {
return WSAGetLastError();
}
-
+
ap_register_cleanup((*new)->cntxt, (void *)(*new),
socket_cleanup, ap_null_cleanup);
return APR_SUCCESS;
diff --git a/network_io/win32/sockopt.c b/network_io/win32/sockopt.c
index 238d48851..047f8940f 100644
--- a/network_io/win32/sockopt.c
+++ b/network_io/win32/sockopt.c
@@ -60,9 +60,9 @@
ap_status_t soblock(SOCKET sd)
{
- int one = 1;
+ int zero = 0;
- if (ioctlsocket(sd, FIONBIO, &one) == SOCKET_ERROR) {
+ if (ioctlsocket(sd, FIONBIO, &zero) == SOCKET_ERROR) {
return WSAGetLastError();
}
return APR_SUCCESS;
@@ -70,9 +70,9 @@ ap_status_t soblock(SOCKET sd)
ap_status_t sononblock(SOCKET sd)
{
- int zero = 0;
+ int one = 1;
- if (ioctlsocket(sd, FIONBIO, &zero) == SOCKET_ERROR) {
+ if (ioctlsocket(sd, FIONBIO, &one) == SOCKET_ERROR) {
return WSAGetLastError();
}
return APR_SUCCESS;
@@ -90,13 +90,40 @@ ap_status_t ap_setsocketopt(ap_socket_t *sock, ap_int32_t opt, ap_int32_t on)
one = 0;
if (opt & APR_SO_TIMEOUT) {
- int timeout;
- sock->timeout = on;
- timeout = on / 1000; /* Windows needs timeout in mSeconds */
- if (setsockopt(sock->sock, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout,
- sizeof(timeout)) == SOCKET_ERROR) {
- return WSAGetLastError();
+ int new_timeout;
+ if (on <= 0)
+ new_timeout = on;
+ else
+ new_timeout = on/1000; /* Windows needs timeout in mSeconds */
+
+ if (new_timeout == 0) {
+ /* Set the socket non-blocking if it isn't already set to non-blocking */
+ if (sock->timeout != 0) {
+ if ((stat = sononblock(sock->sock)) != APR_SUCCESS)
+ return stat;
+ }
+ }
+ else if (new_timeout > 0) {
+ /* Set the socket to blocking if it was previously non-blocking */
+ if (sock->timeout == 0) {
+ if ((stat = soblock(sock->sock)) != APR_SUCCESS)
+ return stat;
+ }
+ /* Reset socket timeouts if the new timeout differs from the old timeout */
+ if (sock->timeout != new_timeout) {
+ setsockopt(sock->sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &new_timeout, sizeof(new_timeout));
+ setsockopt(sock->sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &new_timeout, sizeof(new_timeout));
+ }
+ }
+ else if (new_timeout < 0) {
+ int zero = 0;
+ /* Set the socket to blocking with infinite timeouts */
+ if ((stat = soblock(sock->sock)) != APR_SUCCESS)
+ return stat;
+ setsockopt(sock->sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &zero, sizeof(zero));
+ setsockopt(sock->sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &zero, sizeof(zero));
}
+ sock->timeout = new_timeout;
}
if (opt & APR_SO_KEEPALIVE) {
if (setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, sizeof(int)) == -1) {