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