diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-05-30 12:50:40 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-05-30 12:50:40 +0000 |
commit | e6a7d571d815df563f64444a9adaec0057861f53 (patch) | |
tree | 7b6e1991c42e1c586d0cceb51de3cc7b810fb739 /network_io | |
parent | e99a407e62f708522ad7d986e4fce1df34a3bce0 (diff) | |
download | libapr-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.c | 34 | ||||
-rw-r--r-- | network_io/unix/sockets.c | 3 | ||||
-rw-r--r-- | network_io/unix/sockopt.c | 8 |
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; } |