File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / lighttpd / src / mod_magnet_cache.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:20:06 2014 UTC (10 years ago) by misho
Branches: lighttpd, MAIN
CVS tags: v1_4_35p0, v1_4_35, HEAD
lighttpd 1.4.35

    1: #include "mod_magnet_cache.h"
    2: #include "stat_cache.h"
    3: 
    4: #include <stdlib.h>
    5: #include <time.h>
    6: #include <assert.h>
    7: 
    8: #ifdef HAVE_LUA_H
    9: #include <lualib.h>
   10: #include <lauxlib.h>
   11: 
   12: static script *script_init() {
   13: 	script *sc;
   14: 
   15: 	sc = calloc(1, sizeof(*sc));
   16: 	sc->name = buffer_init();
   17: 	sc->etag = buffer_init();
   18: 
   19: 	return sc;
   20: }
   21: 
   22: static void script_free(script *sc) {
   23: 	if (!sc) return;
   24: 
   25: 	lua_pop(sc->L, 1); /* the function copy */
   26: 
   27: 	buffer_free(sc->name);
   28: 	buffer_free(sc->etag);
   29: 
   30: 	lua_close(sc->L);
   31: 
   32: 	free(sc);
   33: }
   34: 
   35: script_cache *script_cache_init() {
   36: 	script_cache *p;
   37: 
   38: 	p = calloc(1, sizeof(*p));
   39: 
   40: 	return p;
   41: }
   42: 
   43: void script_cache_free(script_cache *p) {
   44: 	size_t i;
   45: 
   46: 	if (!p) return;
   47: 
   48: 	for (i = 0; i < p->used; i++) {
   49: 		script_free(p->ptr[i]);
   50: 	}
   51: 
   52: 	free(p->ptr);
   53: 
   54: 	free(p);
   55: }
   56: 
   57: lua_State *script_cache_get_script(server *srv, connection *con, script_cache *cache, buffer *name) {
   58: 	size_t i;
   59: 	script *sc = NULL;
   60: 	stat_cache_entry *sce;
   61: 
   62: 	for (i = 0; i < cache->used; i++) {
   63: 		sc = cache->ptr[i];
   64: 
   65: 		if (buffer_is_equal(name, sc->name)) {
   66: 			sc->last_used = time(NULL);
   67: 
   68: 			/* oops, the script failed last time */
   69: 
   70: 			if (lua_gettop(sc->L) == 0) break;
   71: 
   72: 			if (HANDLER_ERROR == stat_cache_get_entry(srv, con, sc->name, &sce)) {
   73: 				lua_pop(sc->L, 1); /* pop the old function */
   74: 				break;
   75: 			}
   76: 
   77: 			if (!buffer_is_equal(sce->etag, sc->etag)) {
   78: 				/* the etag is outdated, reload the function */
   79: 				lua_pop(sc->L, 1);
   80: 				break;
   81: 			}
   82: 
   83: 			force_assert(lua_isfunction(sc->L, -1));
   84: 			lua_pushvalue(sc->L, -1); /* copy the function-reference */
   85: 
   86: 			return sc->L;
   87: 		}
   88: 
   89: 		sc = NULL;
   90: 	}
   91: 
   92: 	/* if the script was script already loaded but either got changed or
   93: 	 * failed to load last time */
   94: 	if (sc == NULL) {
   95: 		sc = script_init();
   96: 
   97: 		if (cache->size == 0) {
   98: 			cache->size = 16;
   99: 			cache->ptr = malloc(cache->size * sizeof(*(cache->ptr)));
  100: 		} else if (cache->used == cache->size) {
  101: 			cache->size += 16;
  102: 			cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr)));
  103: 		}
  104: 
  105: 		cache->ptr[cache->used++] = sc;
  106: 
  107: 		buffer_copy_string_buffer(sc->name, name);
  108: 
  109: 		sc->L = luaL_newstate();
  110: 		luaL_openlibs(sc->L);
  111: 	}
  112: 
  113: 	sc->last_used = time(NULL);
  114: 
  115: 	if (0 != luaL_loadfile(sc->L, name->ptr)) {
  116: 		/* oops, an error, return it */
  117: 
  118: 		return sc->L;
  119: 	}
  120: 
  121: 	if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
  122: 		buffer_copy_string_buffer(sc->etag, sce->etag);
  123: 	}
  124: 
  125: 	/**
  126: 	 * pcall() needs the function on the stack
  127: 	 *
  128: 	 * as pcall() will pop the script from the stack when done, we have to
  129: 	 * duplicate it here
  130: 	 */
  131: 	force_assert(lua_isfunction(sc->L, -1));
  132: 	lua_pushvalue(sc->L, -1); /* copy the function-reference */
  133: 
  134: 	return sc->L;
  135: }
  136: 
  137: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>