diff options
author | stoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68> | 2000-06-14 17:16:47 +0000 |
---|---|---|
committer | stoddard <stoddard@13f79535-47bb-0310-9956-ffa450edef68> | 2000-06-14 17:16:47 +0000 |
commit | 913b2ad191416d6122794a41ed8140b45c9a051e (patch) | |
tree | 3facdd31dfe69b1e0f7558bb1000d80019d3434d /network_io | |
parent | 08946f8304d224e2634801b5acda3615f53755cc (diff) | |
download | libapr-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.c | 7 | ||||
-rw-r--r-- | network_io/win32/sockopt.c | 47 |
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) { |