jerenkrantz 01/07/24 09:37:23
Modified: network_io/unix sendrecv.c
Log:
Bring the Solaris sendfilev() in line with the rest of the code in that
it will block after receiving an EAGAIN instead of before the sendfilev().
However, both Solaris and FreeBSD will return EAGAIN even if the write
was successful. This makes it a bit awkward to block after the write
(hence why FreeBSD does it the way it does). Other platforms will
return EAGAIN without having sent anything - after the wait_for_io returns
they need to recall their sendfile. Solaris and FreeBSD can just continue
on their merry way.
- Update *len to be zero when we get an error - the others seem to do this.
- Only wait when it is a timeout not if it is a true non-blocking socket.
Revision Changes Path
1.69 +30 -12 apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -r1.68 -r1.69
--- sendrecv.c 2001/07/24 03:10:59 1.68
+++ sendrecv.c 2001/07/24 16:37:23 1.69
@@ -805,24 +805,42 @@
sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
}
- /* If we are in non-blocking mode, we need to make sure we wait until
- * the other side says it is okay. */
- if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) == 1 ||
- apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
- {
- rv = apr_wait_for_io_or_timeout(sock, 0);
- }
-
/* Actually do the sendfilev */
do {
/* socket, vecs, number of vecs, bytes written */
rv = sendfilev(sock->socketdes, sfv, vecs, &nbytes);
} while (rv == -1 && errno == EINTR);
+
+ /* Solaris returns EAGAIN even though it sent bytes on a non-block sock.
+ * However, if we are on a TIMEOUT socket, we want to block until the
+ * other side has read the data.
+ */
+ if (rv == -1)
+ {
+ if (errno == EAGAIN) {
+ if (apr_is_option_set(sock->netmask, APR_SO_TIMEOUT) == 1)
+ {
+ /* If the wait fails for some reason, we're going to lie to
our
+ * caller and say that we didn't write any bytes. That's
+ * untrue.
+ */
+ rv = apr_wait_for_io_or_timeout(sock, 0);
- /* Solaris returns EAGAIN even though it sent bytes on a non-block sock
*/
- if (rv == -1 && errno != EAGAIN) {
- rv = errno;
- return rv;
+ /* Indicate that we sent zero bytes. */
+ if (rv != APR_SUCCESS)
+ {
+ *len = 0;
+ return rv;
+ }
+ }
+ }
+ else
+ {
+ /* Indicate that we sent zero bytes. */
+ rv = errno;
+ *len = 0;
+ return rv;
+ }
}
/* Update how much we sent */