int WRK_Flush(struct worker *w);
unsigned WRK_Write(struct worker *w, const void *ptr, int len);
unsigned WRK_WriteH(struct worker *w, struct http_hdr *hh, const char *suf);
+#ifdef HAVE_SENDFILE
+void WRK_Sendfile(struct worker *w, int fd, off_t off, unsigned len);
+#endif /* HAVE_SENDFILE */
/* cache_session.c [SES] */
void SES_Init(void);
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_SENDFILE
+#include <sys/uio.h>
+#include <sys/socket.h>
+#endif /* HAVE_SENDFILE */
#include <unistd.h>
#include "heritage.h"
i = writev(*w->wfd, w->iov, w->niov);
if (i != w->liov)
w->werr++;
- else {
- w->liov = 0;
- w->niov = 0;
- }
+ w->liov = 0;
+ w->niov = 0;
return (w->werr);
}
return (len);
}
+#ifdef HAVE_SENDFILE
+void
+WRK_Sendfile(struct worker *w, int fd, off_t off, unsigned len)
+{
+ struct sf_hdtr sfh;
+ int i;
+
+ CHECK_OBJ_NOTNULL(w, WORKER_MAGIC);
+ assert(fd >= 0);
+ assert(len > 0);
+
+ memset(&sfh, 0, sizeof sfh);
+ if (w->niov > 0) {
+ sfh.headers = w->iov;
+ sfh.hdr_cnt = w->niov;
+ }
+ i = sendfile(fd, *w->wfd, off, len, &sfh, NULL, 0);
+ if (i != 0)
+ w->werr++;
+ w->liov = 0;
+ w->niov = 0;
+}
+#endif /* HAVE_SENDFILE */
+
/*--------------------------------------------------------------------*/
static void
assert(st->stevedore != NULL);
u += st->len;
sp->wrk->acct.bodybytes += st->len;
+#ifdef HAVE_SENDFILE
+ /*
+ * XXX: the overhead of setting up senddile is not
+ * XXX: epsilon and maybe not even delta, so avoid
+ * XXX: engaging sendfile for small objects.
+ * XXX: Should use getpagesize() ?
+ */
+ if (st->fd >= 0 && st->len >= 8192) {
+ WRK_Sendfile(sp->wrk, st->fd,
+ st->where, st->len);
+ continue;
+ }
+#endif /* HAVE_SENDFILE */
WRK_Write(sp->wrk, st->ptr, st->len);
}
assert(u == sp->obj->len);