Annotation of embedaddon/lighttpd/src/mod_magnet_cache.c, revision 1.1
1.1 ! misho 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: 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: 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>