summaryrefslogtreecommitdiff
path: root/src/network_gthread_freebsd_sendfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network_gthread_freebsd_sendfile.c')
-rw-r--r--src/network_gthread_freebsd_sendfile.c265
1 files changed, 0 insertions, 265 deletions
diff --git a/src/network_gthread_freebsd_sendfile.c b/src/network_gthread_freebsd_sendfile.c
deleted file mode 100644
index 639eda67..00000000
--- a/src/network_gthread_freebsd_sendfile.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * make sure _GNU_SOURCE is defined
- */
-#include "settings.h"
-#include "network_backends.h"
-#if defined(USE_GTHREAD_FREEBSD_SENDFILE)
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include "network.h"
-#include "fdevent.h"
-#include "log.h"
-#include "stat_cache.h"
-#include "joblist.h"
-#include "timing.h"
-
-#include "sys-files.h"
-#include "sys-socket.h"
-
-typedef struct {
- chunk *c;
-
- void *con;
-
- int sock_fd;
-} write_job;
-
-static write_job *write_job_init() {
- write_job *wj = calloc(1, sizeof(*wj));
-
- return wj;
-}
-
-static void write_job_free(write_job *wj) {
- if (!wj) return;
-
- free(wj);
-}
-
-#define kByte * (1024)
-#define MByte * (1024 kByte)
-
-/**
- * log the time-stamps of the different stages
- */
-static void timing_print(server *srv, connection *con) {
- if (!srv->srvconf.log_timing) return;
-
- TRACE("write-start: %ld.%06ld "
- "read-queue-wait: %ld ms "
- "read-time: %ld ms "
- "write-time: %ld ms ",
- con->timestamps[TIME_SEND_WRITE_START].tv_sec,
- con->timestamps[TIME_SEND_WRITE_START].tv_usec,
-
- TIME_DIFF(TIME_SEND_ASYNC_READ_START, TIME_SEND_ASYNC_READ_QUEUED),
- TIME_DIFF(TIME_SEND_ASYNC_READ_END, TIME_SEND_ASYNC_READ_START),
- TIME_DIFF(TIME_SEND_WRITE_END, TIME_SEND_ASYNC_READ_END_QUEUED)
- );
-}
-
-/**
- * a backend which calls sendfile() in a thread
- */
-
-gpointer network_gthread_freebsd_sendfile_read_thread(gpointer _srv) {
- server *srv = (server *)_srv;
-
- GAsyncQueue * inq;
-
- g_async_queue_ref(srv->aio_write_queue);
-
- inq = srv->aio_write_queue;
-
- /* */
- while (!srv->is_shutdown) {
- write_job *wj = NULL;
-
- if ((wj = g_async_queue_pop(inq))) {
- /* let's see what we have to stat */
- off_t r;
- off_t offset;
- size_t toSend;
- chunk *c;
- connection *con;
- off_t max_toSend = 512 kByte; /** should be larger than the send buffer */
-
- if(wj == (write_job *) 1)
- continue; /* just notifying us that srv->is_shutdown changed */
-
- c = wj->c;
- con = wj->con;
- offset = c->file.start + c->offset;
-
- toSend = c->file.length - c->offset > max_toSend ?
- max_toSend : c->file.length - c->offset;
-
- timing_log(srv, con, TIME_SEND_ASYNC_READ_START);
-
- r = 0;
- if (-1 == sendfile(c->file.fd, wj->sock_fd, offset, toSend, NULL, &r, 0)) {
- switch (errno) {
- case EAGAIN:
- case EINTR:
- c->async.ret_val = NETWORK_STATUS_WAIT_FOR_EVENT;
- break;
- case ENOTCONN:
- c->async.ret_val = NETWORK_STATUS_CONNECTION_CLOSE;
- break;
- default:
- ERROR("sendfile(%s) failed: %s (%d)",
- SAFE_BUF_STR(c->file.name),
- strerror(errno), errno);
- c->async.ret_val = NETWORK_STATUS_FATAL_ERROR;
- break;
- }
- } else if (r == 0) {
- c->async.ret_val = NETWORK_STATUS_CONNECTION_CLOSE;
- } else {
- c->async.written = r;
- }
-
- timing_log(srv, con, TIME_SEND_ASYNC_READ_END);
- timing_log(srv, con, TIME_SEND_ASYNC_READ_END_QUEUED);
-
- /* read async, write as usual */
- joblist_async_append(srv, wj->con);
-
- write_job_free(wj);
- }
- }
-
- g_async_queue_unref(srv->aio_write_queue);
-
- return NULL;
-
-}
-
-
-NETWORK_BACKEND_WRITE(gthreadfreebsdsendfile) {
- chunk *c, *tc;
- size_t chunks_written = 0;
-
- for(c = cq->first; c; c = c->next, chunks_written++) {
- int chunk_finished = 0;
- network_status_t ret;
-
- switch(c->type) {
- case MEM_CHUNK:
- ret = network_write_chunkqueue_writev_mem(srv, con, sock, cq, c);
-
- /* check which chunks are finished now */
- for (tc = c; tc && chunk_is_done(tc); tc = tc->next) {
- /* skip the first c->next as that will be done by the c = c->next in the other for()-loop */
- if (chunk_finished) {
- c = c->next;
- } else {
- chunk_finished = 1;
- }
- }
-
- if (ret != NETWORK_STATUS_SUCCESS) {
- return ret;
- }
-
- break;
- case FILE_CHUNK: {
- /* we might be on our way back from the async request and have a status-code */
- if (c->async.ret_val != NETWORK_STATUS_UNSET) {
- ret = c->async.ret_val;
-
- c->async.ret_val = NETWORK_STATUS_UNSET;
-
- return ret;
- }
-
- /* open file if not already opened */
- if (-1 == c->file.fd) {
- if (-1 == (c->file.fd = open(c->file.name->ptr, O_RDONLY /* | O_DIRECT */ | (srv->srvconf.use_noatime ? O_NOATIME : 0)))) {
- ERROR("opening '%s' failed: %s", SAFE_BUF_STR(c->file.name), strerror(errno));
-
- return NETWORK_STATUS_FATAL_ERROR;
- }
-#ifdef FD_CLOEXEC
- fcntl(c->file.fd, F_SETFD, FD_CLOEXEC);
-#endif
-#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_SEQUENTIAL)
- /* tell the kernel that we want to stream the file */
- if (-1 == posix_fadvise(c->file.fd, c->file.start, c->file.length, POSIX_FADV_SEQUENTIAL)) {
- if (ENOSYS != errno) {
- ERROR("posix_fadvise(%s) failed: %s (%d)", c->file.name->ptr, strerror(errno), errno);
- }
- }
-#endif
- }
-
- if (c->async.written > 0) {
- /* the backend has written something */
-
- c->offset += c->async.written; /* global offset in the file */
- cq->bytes_out += c->async.written;
-
- /* this block is sent, get a new one */
- timing_log(srv, con, TIME_SEND_WRITE_END);
-
- timing_print(srv, con);
-
- c->async.written = -1;
- }
-
- if (c->offset == c->file.length) {
- chunk_finished = 1;
-
- if (c->file.fd != -1) {
- close(c->file.fd);
- c->file.fd = -1;
- }
- } else {
- /* start this write */
- write_job *wj;
-
- timing_log(srv, con, TIME_SEND_WRITE_START);
- wj = write_job_init();
- wj->c = c;
- wj->con = con;
- wj->sock_fd = sock->fd;
-
- c->async.written = -1;
- c->async.ret_val = NETWORK_STATUS_UNSET;
-
- g_async_queue_push(srv->aio_write_queue, wj);
-
- timing_log(srv, con, TIME_SEND_ASYNC_READ_QUEUED);
-
- return NETWORK_STATUS_WAIT_FOR_AIO_EVENT;
- }
-
- break;
- }
- case UNUSED_CHUNK:
- continue;
- }
-
- if (!chunk_finished) {
- /* not finished yet */
-
- return NETWORK_STATUS_WAIT_FOR_EVENT;
- }
- }
-
- return NETWORK_STATUS_SUCCESS;
-}
-
-#endif
-