From: Wez Furlong Date: Sat, 15 Feb 2003 15:11:57 +0000 (+0000) Subject: MFH: Fix for Bug #21809 (select() never times out during socket shutdown) X-Git-Tag: php-4.3.2RC1~203 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f695a4c3b6fbc282633380fd28591fe981ebff0c;p=php MFH: Fix for Bug #21809 (select() never times out during socket shutdown) --- diff --git a/main/network.c b/main/network.c index 133a06850b..51b46b8f18 100644 --- a/main/network.c +++ b/main/network.c @@ -599,6 +599,7 @@ PHPAPI php_stream *_php_stream_sock_open_from_socket(int socket, const char *per sock->is_blocked = 1; sock->timeout.tv_sec = FG(default_socket_timeout); + sock->timeout.tv_usec = 0; sock->socket = socket; stream = php_stream_alloc_rel(&php_stream_socket_ops, sock, persistent_id, "r+"); @@ -974,6 +975,7 @@ static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; fd_set wrfds, efds; int n; + struct timeval timeout; if (close_handle) { #if HAVE_OPENSSL_EXT @@ -990,13 +992,21 @@ static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) /* prevent more data from coming in */ shutdown(sock->socket, SHUT_RD); - /* make sure that the OS sends all data before we close the connection */ + /* try to make sure that the OS sends all data before we close the connection. + * Essentially, we are waiting for the socket to become writeable, which means + * that all pending data has been sent. + * We use a small timeout which should encourage the OS to send the data, + * but at the same time avoid hanging indefintely. + * */ do { FD_ZERO(&wrfds); FD_SET(sock->socket, &wrfds); efds = wrfds; + + timeout.tv_sec = 0; + timeout.tv_usec = 5000; /* arbitrary */ - n = select(sock->socket + 1, NULL, &wrfds, &efds, NULL); + n = select(sock->socket + 1, NULL, &wrfds, &efds, &timeout); } while (n == -1 && php_socket_errno() == EINTR); closesocket(sock->socket);