summaryrefslogtreecommitdiff
path: root/src/mod_magnet_cache.c
diff options
context:
space:
mode:
authorJan Kneschke <jan@kneschke.de>2006-09-10 22:01:43 +0000
committerJan Kneschke <jan@kneschke.de>2006-09-10 22:01:43 +0000
commitdaeab348cdcbc64c104a6f02accda827668f7024 (patch)
treee6712549009c81fa1618d02f2e5d6831f6314be0 /src/mod_magnet_cache.c
parent1311a6137f23cd88ff55a61a9150e8a0b3efb6dd (diff)
downloadlighttpd-git-daeab348cdcbc64c104a6f02accda827668f7024.tar.gz
added mod_magnet
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.11-ssl-fixes@1292 152afb58-edef-0310-8abb-c4023f1b3aa9
Diffstat (limited to 'src/mod_magnet_cache.c')
-rw-r--r--src/mod_magnet_cache.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/mod_magnet_cache.c b/src/mod_magnet_cache.c
new file mode 100644
index 00000000..8fe9a1b7
--- /dev/null
+++ b/src/mod_magnet_cache.c
@@ -0,0 +1,133 @@
+#include <stdlib.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include <time.h>
+#include <assert.h>
+
+#include "mod_magnet_cache.h"
+#include "stat_cache.h"
+
+script *script_init() {
+ script *sc;
+
+ sc = calloc(1, sizeof(*sc));
+ sc->name = buffer_init();
+ sc->etag = buffer_init();
+
+ return sc;
+}
+
+void script_free(script *sc) {
+ if (!sc) return;
+
+ lua_pop(sc->L, 1); /* the function copy */
+
+ buffer_free(sc->name);
+ buffer_free(sc->etag);
+
+ lua_close(sc->L);
+
+ free(sc);
+}
+
+script_cache *script_cache_init() {
+ script_cache *p;
+
+ p = calloc(1, sizeof(*p));
+
+ return p;
+}
+
+void script_cache_free(script_cache *p) {
+ size_t i;
+
+ if (!p) return;
+
+ for (i = 0; i < p->used; i++) {
+ script_free(p->ptr[i]);
+ }
+
+ free(p->ptr);
+
+ free(p);
+}
+
+lua_State *script_cache_get_script(server *srv, connection *con, script_cache *cache, buffer *name) {
+ size_t i;
+ script *sc = NULL;
+ stat_cache_entry *sce;
+
+ for (i = 0; i < cache->used; i++) {
+ sc = cache->ptr[i];
+
+ if (buffer_is_equal(name, sc->name)) {
+ sc->last_used = time(NULL);
+
+ /* oops, the script failed last time */
+
+ if (lua_gettop(sc->L) == 0) break;
+
+ if (HANDLER_ERROR == stat_cache_get_entry(srv, con, sc->name, &sce)) {
+ lua_pop(sc->L, 1); /* pop the old function */
+ break;
+ }
+
+ if (!buffer_is_equal(sce->etag, sc->etag)) {
+ /* the etag is outdated, reload the function */
+ lua_pop(sc->L, 1);
+ break;
+ }
+
+ assert(lua_isfunction(sc->L, -1));
+ lua_pushvalue(sc->L, -1); /* copy the function-reference */
+
+ return sc->L;
+ }
+
+ sc = NULL;
+ }
+
+ /* if the script was script already loaded but either got changed or
+ * failed to load last time */
+ if (sc == NULL) {
+ sc = script_init();
+
+ if (cache->size == 0) {
+ cache->size = 16;
+ cache->ptr = malloc(cache->size * sizeof(*(cache->ptr)));
+ } else if (cache->used == cache->size) {
+ cache->size += 16;
+ cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr)));
+ }
+
+ cache->ptr[cache->used++] = sc;
+
+ buffer_copy_string_buffer(sc->name, name);
+
+ sc->L = luaL_newstate();
+ luaL_openlibs(sc->L);
+ }
+
+ sc->last_used = time(NULL);
+
+ if (0 != luaL_loadfile(sc->L, name->ptr)) {
+ /* oops, an error, return it */
+
+ return sc->L;
+ }
+
+ if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
+ buffer_copy_string_buffer(sc->etag, sce->etag);
+ }
+
+ /**
+ * pcall() needs the function on the stack
+ *
+ * as pcall() will pop the script from the stack when done, we have to
+ * duplicate it here
+ */
+ assert(lua_isfunction(sc->L, -1));
+ lua_pushvalue(sc->L, -1); /* copy the function-reference */
+
+ return sc->L;
+}