- next is 1.4.56
[lighttpd.git] / src / mod_magnet_cache.c
blob9f09cca22bad16474b81ccc876d917390a18f99e
1 #include "first.h"
3 #include "mod_magnet_cache.h"
4 #include "base.h"
5 #include "stat_cache.h"
7 #include <stdlib.h>
8 #include <time.h>
10 #include <lualib.h>
11 #include <lauxlib.h>
13 static script *script_init() {
14 script *sc;
16 sc = calloc(1, sizeof(*sc));
17 sc->name = buffer_init();
18 sc->etag = buffer_init();
20 return sc;
23 static void script_free(script *sc) {
24 if (!sc) return;
26 lua_pop(sc->L, 1); /* the function copy */
28 buffer_free(sc->name);
29 buffer_free(sc->etag);
31 lua_close(sc->L);
33 free(sc);
36 script_cache *script_cache_init() {
37 script_cache *p;
39 p = calloc(1, sizeof(*p));
41 return p;
44 void script_cache_free(script_cache *p) {
45 size_t i;
47 if (!p) return;
49 for (i = 0; i < p->used; i++) {
50 script_free(p->ptr[i]);
53 free(p->ptr);
55 free(p);
58 lua_State *script_cache_get_script(server *srv, connection *con, script_cache *cache, buffer *name) {
59 size_t i;
60 script *sc = NULL;
61 stat_cache_entry *sce;
63 for (i = 0; i < cache->used; i++) {
64 sc = cache->ptr[i];
66 if (buffer_is_equal(name, sc->name)) {
67 sc->last_used = time(NULL);
69 /* oops, the script failed last time */
71 if (lua_gettop(sc->L) == 0) break;
72 force_assert(lua_gettop(sc->L) == 1);
74 if (HANDLER_ERROR == stat_cache_get_entry(srv, con, sc->name, &sce)) {
75 lua_pop(sc->L, 1); /* pop the old function */
76 break;
79 stat_cache_etag_get(sce, con->etag_flags);
80 if (!buffer_is_equal(sce->etag, sc->etag)) {
81 /* the etag is outdated, reload the function */
82 lua_pop(sc->L, 1);
83 break;
86 force_assert(lua_isfunction(sc->L, -1));
88 return sc->L;
91 sc = NULL;
94 /* if the script was script already loaded but either got changed or
95 * failed to load last time */
96 if (sc == NULL) {
97 sc = script_init();
99 if (cache->used == cache->size) {
100 cache->size += 16;
101 cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr)));
104 cache->ptr[cache->used++] = sc;
106 buffer_copy_buffer(sc->name, name);
108 sc->L = luaL_newstate();
109 luaL_openlibs(sc->L);
112 sc->last_used = time(NULL);
114 if (0 != luaL_loadfile(sc->L, name->ptr)) {
115 /* oops, an error, return it */
116 return sc->L;
119 if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
120 buffer_copy_buffer(sc->etag, stat_cache_etag_get(sce, con->etag_flags));
123 force_assert(lua_isfunction(sc->L, -1));
125 return sc->L;