X-Git-Url: https://gitweb.ps.run/ps-cgit/blobdiff_plain/f32a2da636ffa6eaa6b8d0d3f35a673fa12e404a..d3581b58890389794de5d5222c91a0129873e95c:/cache.c diff --git a/cache.c b/cache.c index aa870e3..9e7eeb0 100644 --- a/cache.c +++ b/cache.c @@ -1,6 +1,6 @@ /* cache.c: cache management * - * Copyright (C) 2006 Lars Hjemli + * Copyright (C) 2006-2014 cgit Development Team * * Licensed under GNU General Public License v2 * (see COPYING for full license text) @@ -13,6 +13,9 @@ * */ +#ifdef HAVE_LINUX_SENDFILE +#include +#endif #include "cgit.h" #include "cache.h" #include "html.h" @@ -24,14 +27,12 @@ struct cache_slot { int keylen; int ttl; cache_fill_fn fn; - void *cbdata; int cache_fd; int lock_fd; const char *cache_name; const char *lock_name; int match; struct stat cache_st; - struct stat lock_st; int bufsize; char buf[CACHE_BUFSIZE]; }; @@ -82,6 +83,23 @@ static int close_slot(struct cache_slot *slot) /* Print the content of the active cache slot (but skip the key). */ static int print_slot(struct cache_slot *slot) { +#ifdef HAVE_LINUX_SENDFILE + off_t start_off; + int ret; + + start_off = slot->keylen + 1; + + do { + ret = sendfile(STDOUT_FILENO, slot->cache_fd, &start_off, + slot->cache_st.st_size - start_off); + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + return errno; + } + return 0; + } while (1); +#else ssize_t i, j; i = lseek(slot->cache_fd, slot->keylen + 1, SEEK_SET); @@ -98,6 +116,7 @@ static int print_slot(struct cache_slot *slot) return errno; else return 0; +#endif } /* Check if the slot has expired */ @@ -187,7 +206,11 @@ static int fill_slot(struct cache_slot *slot) return errno; /* Generate cache content */ - slot->fn(slot->cbdata); + slot->fn(); + + /* update stat info */ + if (fstat(slot->lock_fd, &slot->cache_st)) + return errno; /* Restore stdout */ if (dup2(tmp, STDOUT_FILENO) == -1) @@ -277,7 +300,7 @@ static int process_slot(struct cache_slot *slot) if ((err = lock_slot(slot)) != 0) { cache_log("[cgit] Unable to lock slot %s: %s (%d)\n", slot->lock_name, strerror(err), err); - slot->fn(slot->cbdata); + slot->fn(); return 0; } @@ -286,7 +309,7 @@ static int process_slot(struct cache_slot *slot) slot->lock_name, strerror(err), err); unlock_slot(slot, 0); close_lock(slot); - slot->fn(slot->cbdata); + slot->fn(); return 0; } // We've got a valid cache slot in the lock file, which @@ -310,7 +333,7 @@ static int process_slot(struct cache_slot *slot) /* Print cached content to stdout, generate the content if necessary. */ int cache_process(int size, const char *path, const char *key, int ttl, - cache_fill_fn fn, void *cbdata) + cache_fill_fn fn) { unsigned long hash; int i; @@ -321,14 +344,14 @@ int cache_process(int size, const char *path, const char *key, int ttl, /* If the cache is disabled, just generate the content */ if (size <= 0) { - fn(cbdata); + fn(); return 0; } /* Verify input, calculate filenames */ if (!path) { cache_log("[cgit] Cache path not specified, caching is disabled\n"); - fn(cbdata); + fn(); return 0; } if (!key) @@ -343,7 +366,6 @@ int cache_process(int size, const char *path, const char *key, int ttl, strbuf_addbuf(&lockname, &filename); strbuf_addstr(&lockname, ".lock"); slot.fn = fn; - slot.cbdata = cbdata; slot.ttl = ttl; slot.cache_name = filename.buf; slot.lock_name = lockname.buf; @@ -376,7 +398,7 @@ int cache_ls(const char *path) DIR *dir; struct dirent *ent; int err = 0; - struct cache_slot slot; + struct cache_slot slot = { 0 }; struct strbuf fullname = STRBUF_INIT; size_t prefixlen;