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>