You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by je...@apache.org on 2001/07/24 05:02:58 UTC
cvs commit: apr/network_io/unix sendrecv.c
jerenkrantz 01/07/23 20:02:58
Modified: . CHANGES configure.in
network_io/unix sendrecv.c
Log:
Add Solaris 8 sendfilev() support.
Passes the sendfile client/server test in apr.
Tested on Solaris 8/Sparc with latest recommended patches and the patches
as listed in:
http://sunsolve.Sun.COM/pub-cgi/retrieve.pl?doc=fpatches%2F111297 (Sparc)
http://sunsolve.Sun.COM/pub-cgi/retrieve.pl?doc=fpatches%2F111298 (x86)
Revision Changes Path
1.125 +4 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -r1.124 -r1.125
--- CHANGES 2001/07/23 03:28:30 1.124
+++ CHANGES 2001/07/24 03:02:58 1.125
@@ -1,5 +1,9 @@
Changes with APR b1
+ *) Add Solaris 8's sendfilev() support. This requires the following
+ patches from Sun: 111297 (Sparc), 111298 (x86). You'll need the
+ other patches listed in the patch description. [Justin Erenkrantz]
+
*) Close file descriptor when we are done with fcntl or flock-based
cross-process lock. Otherwise, we leak descriptors.
[Justin Erenkrantz]
1.342 +2 -1 apr/configure.in
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.341
retrieving revision 1.342
diff -u -r1.341 -r1.342
--- configure.in 2001/07/23 12:30:52 1.341
+++ configure.in 2001/07/24 03:02:58 1.342
@@ -466,7 +466,8 @@
AC_CHECK_FUNCS(getrlimit, [ have_getrlimit="1" ], [ have_getrlimit="0" ])
AC_CHECK_FUNCS(writev)
sendfile="0"
-AC_CHECK_FUNCS(sendfile send_file, [ sendfile="1" ])
+AC_CHECK_LIB(sendfile, sendfilev)
+AC_CHECK_FUNCS(sendfile send_file sendfilev, [ sendfile="1" ])
dnl THIS MUST COME AFTER THE THREAD TESTS - FreeBSD doesn't always have a
dnl threaded poll() and we don't want to use sendfile on early FreeBSD
1.67 +87 -0 apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- sendrecv.c 2001/07/10 15:01:37 1.66
+++ sendrecv.c 2001/07/24 03:02:58 1.67
@@ -742,6 +742,93 @@
* we don't use it until it is fixed. If it is used as it is now, it will
* hang the machine and the only way to fix it is a reboot.
*/
+#elif defined(HAVE_SENDFILEV)
+/* Solaris 8's sendfilev() interface
+ *
+ * SFV_FD_SELF refers to our memory space.
+ *
+ * Required Sparc patches (or newer):
+ * 111297-01, 108528-09, 109472-06, 109234-03, 108995-02, 111295-01, 109025-03,
+ * 108991-13
+ * Required x86 patches (or newer):
+ * 111298-01, 108529-09, 109473-06, 109235-04, 108996-02, 111296-01, 109026-04,
+ * 108992-13
+ */
+apr_status_t apr_sendfile(apr_socket_t *sock, apr_file_t *file,
+ apr_hdtr_t *hdtr, apr_off_t *offset, apr_size_t *len,
+ apr_int32_t flags)
+{
+ apr_status_t rv;
+ size_t nbytes;
+ sendfilevec_t *sfv;
+ int vecs, curvec, i;
+
+ if (!hdtr) {
+ hdtr = &no_hdtr;
+ }
+
+ /* Ignore flags for now. */
+ flags = 0;
+
+ /* Calculate how much space we need. */
+ vecs = hdtr->numheaders + hdtr->numtrailers + 1;
+ sfv = apr_palloc(sock->cntxt, sizeof(sendfilevec_t) * vecs);
+
+ curvec = 0;
+
+ /* Add the headers */
+ for (i = 0; i < hdtr->numheaders; i++, curvec++) {
+ sfv[curvec].sfv_fd = SFV_FD_SELF;
+ sfv[curvec].sfv_flag = 0;
+ sfv[curvec].sfv_off = hdtr->headers[i].iov_base;
+ sfv[curvec].sfv_len = hdtr->headers[i].iov_len;
+ }
+
+ /* If the len is 0, we skip the file. */
+ if (*len)
+ {
+ sfv[curvec].sfv_fd = file->filedes;
+ sfv[curvec].sfv_flag = 0;
+ sfv[curvec].sfv_off = *offset;
+ sfv[curvec].sfv_len = *len;
+
+ curvec++;
+ }
+ else
+ vecs--;
+
+ /* Add the footers */
+ for (i = 0; i < hdtr->numtrailers; i++, curvec++) {
+ sfv[curvec].sfv_fd = SFV_FD_SELF;
+ sfv[curvec].sfv_flag = 0;
+ sfv[curvec].sfv_off = hdtr->trailers[i].iov_base;
+ 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 */
+ if (rv == -1 && errno != EAGAIN) {
+ rv = errno;
+ return rv;
+ }
+
+ /* Update how much we sent */
+ *len = nbytes;
+ return APR_SUCCESS;
+}
#else
#error APR has detected sendfile on your system, but nobody has written a
#error version of it for APR yet. To get past this, either write apr_sendfile
Re: cvs commit: apr/network_io/unix sendrecv.c
Posted by Jeff Trawick <tr...@attglobal.net>.
jerenkrantz@apache.org writes:
> jerenkrantz 01/07/23 20:02:58
>
> Modified: . CHANGES configure.in
> network_io/unix sendrecv.c
> Log:
> Add Solaris 8 sendfilev() support.
>
> Index: sendrecv.c
> + /* 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);
> + }
1) bug
We shouldn't wait for writability when the app has set the APR
nonblock option. We only do that when the app has set the APR
timeout option to non-zero.
2) performance...
You should check for writability *after* sendfilev() returns
EAGAIN. Otherwise, we get extra syscalls from time to time.
Yeah, rbb made the FreeBSD apr_sendfile() check for writability
first, but it is preferable to call sendfilev() first *then* wait
if needed.
Since a web server will use sendfile() often on small files (e.g.,
.png) you can bet that this will have a bunch of unnecessary
select() calls.
> +
> + /* 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 */
> + if (rv == -1 && errno != EAGAIN) {
> + rv = errno;
> + return rv;
> + }
--
Jeff Trawick | trawick@attglobal.net | PGP public key at web site:
http://www.geocities.com/SiliconValley/Park/9289/
Born in Roswell... married an alien...