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>