summaryrefslogtreecommitdiff
path: root/network_io
diff options
context:
space:
mode:
authortrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-05-30 12:50:40 +0000
committertrawick <trawick@13f79535-47bb-0310-9956-ffa450edef68>2003-05-30 12:50:40 +0000
commite6a7d571d815df563f64444a9adaec0057861f53 (patch)
tree7b6e1991c42e1c586d0cceb51de3cc7b810fb739 /network_io
parente99a407e62f708522ad7d986e4fce1df34a3bce0 (diff)
downloadlibapr-e6a7d571d815df563f64444a9adaec0057861f53.tar.gz
Fix some problems with non-blocking socket handling on unix
that resulted in infinite timeouts being used for non-blocking sockets with apr_socket_connect() and some read/write calls. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64522 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'network_io')
-rw-r--r--network_io/unix/sendrecv.c34
-rw-r--r--network_io/unix/sockets.c3
-rw-r--r--network_io/unix/sockopt.c8
3 files changed, 24 insertions, 21 deletions
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index f12aff869..46bbe7271 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -80,7 +80,7 @@ apr_status_t apr_socket_send(apr_socket_t *sock, const char *buf,
} while (rv == -1 && errno == EINTR);
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
- && sock->timeout != 0) {
+ && apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv;
do_select:
arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
@@ -98,7 +98,7 @@ do_select:
*len = 0;
return errno;
}
- if (sock->timeout && rv < *len) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) && rv < *len) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
(*len) = rv;
@@ -120,7 +120,7 @@ apr_status_t apr_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
} while (rv == -1 && errno == EINTR);
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout != 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
do_select:
arv = apr_wait_for_io_or_timeout(NULL, sock, 1);
if (arv != APR_SUCCESS) {
@@ -137,7 +137,7 @@ do_select:
(*len) = 0;
return errno;
}
- if (sock->timeout && rv < *len) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) && rv < *len) {
sock->netmask |= APR_INCOMPLETE_READ;
}
(*len) = rv;
@@ -160,7 +160,7 @@ apr_status_t apr_socket_sendto(apr_socket_t *sock, apr_sockaddr_t *where,
} while (rv == -1 && errno == EINTR);
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
- && sock->timeout != 0) {
+ && apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
@@ -193,7 +193,7 @@ apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock,
} while (rv == -1 && errno == EINTR);
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout != 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 1);
if (arv != APR_SUCCESS) {
*len = 0;
@@ -240,7 +240,7 @@ apr_status_t apr_socket_sendv(apr_socket_t * sock, const struct iovec *vec,
} while (rv == -1 && errno == EINTR);
if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout != 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv;
do_select:
arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
@@ -258,7 +258,8 @@ do_select:
*len = 0;
return errno;
}
- if (sock->timeout && rv < requested_len) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) &&
+ rv < requested_len) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
(*len) = rv;
@@ -339,7 +340,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
if (rv == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout > 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
do_select:
arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (arv != APR_SUCCESS) {
@@ -374,7 +375,7 @@ do_select:
* partial byte count; this is a non-blocking socket.
*/
- if (sock->timeout) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
return arv;
@@ -522,7 +523,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
if (rv == -1) {
if (errno == EAGAIN) {
- if (sock->timeout) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
/* FreeBSD's sendfile can return -1/EAGAIN even if it
@@ -562,7 +563,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
}
if (rv == -1 &&
errno == EAGAIN &&
- sock->timeout > 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (arv != APR_SUCCESS) {
*len = 0;
@@ -680,7 +681,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
if (rc == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout > 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
apr_status_t arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (arv != APR_SUCCESS) {
@@ -820,7 +821,7 @@ apr_status_t apr_socket_sendfile(apr_socket_t * sock, apr_file_t * file,
if (rv == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout > 0) {
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
do_select:
arv = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (arv != APR_SUCCESS) {
@@ -848,7 +849,7 @@ do_select:
return errno;
}
- if (sock->timeout &&
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) &&
(parms.bytes_sent < (parms.file_bytes + parms.header_length + parms.trailer_length))) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
@@ -984,7 +985,8 @@ apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
/* Update how much we sent */
*len = nbytes;
- if (sock->timeout && (*len < requested_len)) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) &&
+ (*len < requested_len)) {
sock->netmask |= APR_INCOMPLETE_WRITE;
}
return APR_SUCCESS;
diff --git a/network_io/unix/sockets.c b/network_io/unix/sockets.c
index dbc2d2eb2..e1d5c7e80 100644
--- a/network_io/unix/sockets.c
+++ b/network_io/unix/sockets.c
@@ -271,7 +271,8 @@ apr_status_t apr_socket_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
/* we can see EINPROGRESS the first time connect is called on a non-blocking
* socket; if called again, we can see EALREADY
*/
- if (rc == -1 && (errno == EINPROGRESS || errno == EALREADY) && sock->timeout != 0) {
+ if (rc == -1 && (errno == EINPROGRESS || errno == EALREADY) &&
+ apr_is_option_set(sock->netmask, APR_SO_TIMEOUT)) {
rc = apr_wait_for_io_or_timeout(NULL, sock, 0);
if (rc != APR_SUCCESS) {
return rc;
diff --git a/network_io/unix/sockopt.c b/network_io/unix/sockopt.c
index de2526066..c346678cb 100644
--- a/network_io/unix/sockopt.c
+++ b/network_io/unix/sockopt.c
@@ -137,14 +137,14 @@ apr_status_t apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
apr_set_option(&sock->netmask, APR_SO_NONBLOCK, 0);
}
}
- /* must disable the incomplete read support if we change to a
- * blocking socket.
+ /* must disable the incomplete read support if we disable
+ * a timeout
*/
- if (t == 0) {
+ if (t <= 0) {
sock->netmask &= ~APR_INCOMPLETE_READ;
}
sock->timeout = t;
- apr_set_option(&sock->netmask, APR_SO_TIMEOUT, t);
+ apr_set_option(&sock->netmask, APR_SO_TIMEOUT, t > 0);
return APR_SUCCESS;
}