Author: mturk
Date: Thu Aug 11 17:44:33 2011
New Revision: 1156700
URL: http://svn.apache.org/viewvc?rev=1156700&view=rev
Log:
Use a simpler restartable sendfile.
Modified:
commons/sandbox/runtime/trunk/src/main/native/os/linux/sendfile.c
commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c
Modified: commons/sandbox/runtime/trunk/src/main/native/os/linux/sendfile.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/linux/sendfile.c?rev=1156700&r1=1156699&r2=1156700&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/linux/sendfile.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/linux/sendfile.c Thu Aug
11 17:44:33 2011
@@ -43,18 +43,21 @@ ACR_NET_EXPORT(jint, Sendfile, send0)(JN
acr_sd_t *sd = J2P(sp, acr_sd_t *);
acr_sf_t *sf = J2P(fp, acr_sf_t *);
int sock;
+ off_t rdoff;
if ((sock = AcrSdRetain(sd)) == -1) {
ACR_THROW_NET_ERROR(ACR_EBADF);
return -1;
}
+ rdoff = sf->off;
if (sf->size != 0) {
if ((sf->size - sf->off) > INT_MAX)
cnt = INT_MAX;
else
- cnt = sf->size - sf->off;
+ cnt = (size_t)(sf->size - sf->off);
}
if (ACR_HASFLAG(sd, ACR_SO_WPART)) {
+ /* Flush any previous writes */
ACR_CLRFLAG(sd, ACR_SO_WPART);
rc = AcrWaitIO(sock, sd->timeout, POLLOUT);
if (rc != 0)
@@ -64,20 +67,20 @@ ACR_NET_EXPORT(jint, Sendfile, send0)(JN
AcrSdRelease(sd);
return -1;
}
- while (rc == 0) {
+ do {
wr = sendfile(sock, /* socket */
sf->fd, /* file descriptor of the file to be sent */
&sf->off, /* where in the file to start */
cnt); /* number of bytes to send */
- if (wr == -1) {
- if ((errno == EAGAIN || errno == EWOULDBLOCK) && (sd->timeout > 0))
- rc = AcrWaitIO(sock, sd->timeout, POLLOUT);
- else if (errno != EINTR)
- rc = errno;
- }
- else {
- /* Send something */
- break;
+ } while (wr == -1 && errno == EINTR);
+
+ if (wr == -1) {
+ rc = errno;
+ if ((rc == EAGAIN || rc == EWOULDBLOCK) && sd->timeout > 0) {
+ if ((rc = AcrWaitIO(sock, sd->timeout, POLLOUT)) == 0) {
+ /* Send someting */
+ wr = (ssize_t)(sf->off - rdoff);
+ }
}
}
finally:
@@ -85,8 +88,12 @@ finally:
wr = -1;
ACR_THROW_NET_ERROR(rc);
}
- else if (sd->timeout > 0 && wr < cnt)
- sd->flags |= ACR_SO_WPART;
+ else if (sd->timeout > 0 && wr < (ssize_t)(sf->off - rdoff)) {
+ /* Send more then written.
+ * The next send call will have to wait
+ */
+ ACR_SETFLAG(sd, ACR_SO_WPART);
+ }
AcrSdRelease(sd);
return (jint)wr;
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c?rev=1156700&r1=1156699&r2=1156700&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c Thu Aug
11 17:44:33 2011
@@ -35,10 +35,6 @@
*/
#define ZERO_FILE_LINE_CHUNK 4096
-/**
- * XXX: Same code as for Linux?
- * If it happens to be true, combine those into the same file.
- */
ACR_NET_EXPORT(jint, Sendfile, send0)(JNI_STDARGS, jlong sp, jlong fp)
{
int rc = 0;
@@ -47,45 +43,59 @@ ACR_NET_EXPORT(jint, Sendfile, send0)(JN
acr_sd_t *sd = J2P(sp, acr_sd_t *);
acr_sf_t *sf = J2P(fp, acr_sf_t *);
int sock;
+ off_t rdoff;
if ((sock = AcrSdRetain(sd)) == -1) {
ACR_THROW_NET_ERROR(ACR_EBADF);
return -1;
}
+ rdoff = sf->off;
if (sf->size != 0) {
if ((sf->size - sf->off) > INT_MAX)
cnt = INT_MAX;
else
- cnt = sf->size - sf->off;
+ cnt = (size_t)(sf->size - sf->off);
}
if (ACR_HASFLAG(sd, ACR_SO_WPART)) {
+ /* Flush any previous writes */
ACR_CLRFLAG(sd, ACR_SO_WPART);
rc = AcrWaitIO(sock, sd->timeout, POLLOUT);
+ if (rc != 0)
+ goto finally;
+ }
+ if (cnt == 0) {
+ AcrSdRelease(sd);
+ return -1;
}
- while (rc == 0) {
- if (cnt == 0)
- break;
+ do {
wr = sendfile(sock, /* socket */
sf->fd, /* file descriptor of the file to be sent */
&sf->off, /* where in the file to start */
cnt); /* number of bytes to send */
- if (wr == -1) {
- if ((errno == EAGAIN || errno == EWOULDBLOCK) && (sd->timeout > 0))
- rc = AcrWaitIO(sock, sd->timeout, POLLOUT);
- else if (errno != EINTR)
- rc = errno;
- }
- else {
- /* Send something */
- break;
+ } while (wr == -1 && errno == EINTR);
+
+ if (wr == -1) {
+ rc = errno;
+ if ((rc == EAGAIN || rc == EWOULDBLOCK) && sd->timeout > 0) {
+ if ((rc = AcrWaitIO(sock, sd->timeout, POLLOUT)) == 0) {
+ /* We have send someting.
+ * See how many bytes was actually send.
+ */
+ wr = (ssize_t)(sf->off - rdoff);
+ }
}
}
+finally:
if (rc != 0) {
wr = -1;
ACR_THROW_NET_ERROR(rc);
}
- else if (sd->timeout > 0 && wr < cnt)
- sd->flags |= ACR_SO_WPART;
+ else if (sd->timeout > 0 && wr < (ssize_t)(sf->off - rdoff)) {
+ /* Send more then written.
+ * The next send call will have to wait
+ */
+ ACR_SETFLAG(sd, ACR_SO_WPART);
+ }
AcrSdRelease(sd);
return (jint)wr;
}