Author: mturk
Date: Thu Aug 11 06:23:44 2011
New Revision: 1156503
URL: http://svn.apache.org/viewvc?rev=1156503&view=rev
Log:
Solaris sendfile implementation. Seems the same code as on linux can be used
since we don't use headers/trailers
Modified:
commons/sandbox/runtime/trunk/src/main/native/os/solaris/sendfile.c
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=1156503&r1=1156502&r2=1156503&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 06:23:44 2011
@@ -26,3 +26,66 @@
#include "arch_opts.h"
#include "arch_sync.h"
+#include <poll.h>
+#include <sys/sendfile.h>
+
+/**
+ * Used for files that report st_size == 0
+ * like /proc/ file system
+ */
+#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;
+ ssize_t wr = 0;
+ size_t cnt = ZERO_FILE_LINE_CHUNK;
+ acr_sd_t *sd = J2P(sp, acr_sd_t *);
+ acr_sf_t *sf = J2P(fp, acr_sf_t *);
+ int sock;
+
+ if ((sock = AcrSdRetain(sd)) == -1) {
+ ACR_THROW_NET_ERROR(ACR_EBADF);
+ return -1;
+ }
+ if (sf->info.st_size != 0) {
+ if ((sf->info.st_size - sf->off) > INT_MAX)
+ cnt = INT_MAX;
+ else
+ cnt = sf->info.st_size - sf->off;
+ }
+ if (ACR_HASFLAG(sd, ACR_SO_WPART)) {
+ ACR_CLRFLAG(sd, ACR_SO_WPART);
+ rc = AcrWaitIO(sock, sd->timeout, POLLOUT);
+ }
+ while (rc == 0) {
+ if (cnt == 0)
+ break;
+ 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;
+ }
+ }
+ if (rc != 0) {
+ wr = -1;
+ ACR_THROW_NET_ERROR(rc);
+ }
+ else if (sd->timeout > 0 && wr < cnt)
+ sd->flags |= ACR_SO_WPART;
+ AcrSdRelease(sd);
+ return (jint)wr;
+}