Hi! Have attached the patch for vmod_std_fileread.c, now prepended with the license as required.
-- Regards, Sanjoy Das. http://playingwithpointers.com Public Key at http://playingwithpointers.com/custom/public_key.txt
Index: varnish/varnish-cache/lib/libvmod_std/Makefile.am =================================================================== --- varnish.orig/varnish-cache/lib/libvmod_std/Makefile.am 2010-11-26 07:01:56.000000000 +0530 +++ varnish/varnish-cache/lib/libvmod_std/Makefile.am 2010-11-26 22:10:19.000000000 +0530 @@ -9,7 +9,8 @@ libvmod_std_la_SOURCES = \ vcc_if.c \ vcc_if.h \ - vmod_std.c + vmod_std.c \ + vmod_std_fileread.c vcc_if.c vcc_if.h: $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc @PYTHON@ $(top_srcdir)/lib/libvmod_std/vmod.py $(top_srcdir)/lib/libvmod_std/vmod.vcc Index: varnish/varnish-cache/lib/libvmod_std/vmod.vcc =================================================================== --- varnish.orig/varnish-cache/lib/libvmod_std/vmod.vcc 2010-11-26 07:01:56.000000000 +0530 +++ varnish/varnish-cache/lib/libvmod_std/vmod.vcc 2010-11-26 22:10:19.000000000 +0530 @@ -33,3 +33,4 @@ Function REAL random(REAL, REAL) Function VOID log(STRING_LIST) Function VOID syslog(INT, STRING_LIST) +Function STRING fileread(PRIV_CALL, STRING) Index: varnish/varnish-cache/lib/libvmod_std/vmod_std_fileread.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ varnish/varnish-cache/lib/libvmod_std/vmod_std_fileread.c 2010-11-26 22:12:05.000000000 +0530 @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2010 Linpro AS + * All rights reserved. + * + * Author: Sanjoy Das <[email protected]> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <fcntl.h> +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include "vrt.h" +#include "../../bin/varnishd/cache.h" + +#include "vcc_if.h" + +VSLIST_HEAD(cached_file_list, cached_file); + +struct cached_file { + unsigned magic; +#define CACHED_FILE_MAGIC 0xa8e9d87a + char *file_name; + char *contents; + time_t last_modification; + off_t file_sz; + VSLIST_ENTRY(cached_file) next; +}; + +static void +free_cached_files(void *file_list) +{ + struct cached_file *iter, *tmp; + struct cached_file_list *list = file_list; + VSLIST_FOREACH_SAFE(iter, list, next, tmp) { + CHECK_OBJ(iter, CACHED_FILE_MAGIC); + free(iter->file_name); + free(iter->contents); + FREE_OBJ(iter); + } + free(file_list); +} + +static pthread_rwlock_t filelist_lock = PTHREAD_RWLOCK_INITIALIZER; +static int filelist_update = 0; + +const char * +vmod_fileread(struct sess *sp, struct vmod_priv *priv, const char *file_name) +{ + struct cached_file *iter = NULL; + struct stat buf; + struct cached_file_list *list; + int fd, my_filelist_update; + + (void)sp; + + AZ(pthread_rwlock_rdlock(&filelist_lock)); + + if (priv->free == NULL) { + AZ(pthread_rwlock_unlock(&filelist_lock)); + /* + * Another thread may already have initialized priv + * here, making the repeat check necessary. + */ + AZ(pthread_rwlock_wrlock(&filelist_lock)); + if (priv->free == NULL) { + priv->free = free_cached_files; + priv->priv = malloc(sizeof(struct cached_file_list)); + AN(priv->priv); + list = priv->priv; + VSLIST_INIT(list); + } + AZ(pthread_rwlock_unlock(&filelist_lock)); + AZ(pthread_rwlock_rdlock(&filelist_lock)); + } else { + list = priv->priv; + VSLIST_FOREACH(iter, list, next) { + CHECK_OBJ(iter, CACHED_FILE_MAGIC); + if (strcmp(iter->file_name, file_name) == 0) { + /* This thread was holding a read lock. */ + AZ(pthread_rwlock_unlock(&filelist_lock)); + return iter->contents; + } + } + } + + my_filelist_update = filelist_update; + + /* This thread was holding a read lock. */ + AZ(pthread_rwlock_unlock(&filelist_lock)); + + if ((fd = open(file_name, O_RDONLY)) == -1) + return ""; + + fstat(fd, &buf); + + AZ(pthread_rwlock_wrlock(&filelist_lock)); + + if (my_filelist_update != filelist_update) { + + /* + * Small optimization: search through the linked list again + * only if something has been changed. + */ + VSLIST_FOREACH(iter, list, next) { + CHECK_OBJ(iter, CACHED_FILE_MAGIC); + if (strcmp(iter->file_name, file_name) == 0) { + /* This thread was holding a write lock. */ + AZ(pthread_rwlock_unlock(&filelist_lock)); + return iter->contents; + } + } + } + + ALLOC_OBJ(iter, CACHED_FILE_MAGIC); + AN(iter); + + iter->file_name = strdup(file_name); + iter->last_modification = buf.st_mtime; + + iter->contents = malloc(buf.st_size + 1); + AN(iter->contents); + iter->file_sz = read(fd, iter->contents, buf.st_size); + assert(iter->file_sz == buf.st_size); + AZ(close(fd)); + + iter->contents[iter->file_sz] = '\0'; + + VSLIST_INSERT_HEAD(list, iter, next); + + filelist_update++; + + /* This thread was holding a write lock. */ + AZ(pthread_rwlock_unlock(&filelist_lock)); + return iter->contents; +}
_______________________________________________ varnish-dev mailing list [email protected] http://lists.varnish-cache.org/mailman/listinfo/varnish-dev
