]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Add LuaCodeCache directive for controlling in-memory caching.
authorDaniel Gruno <humbedooh@apache.org>
Sun, 29 Jul 2012 19:07:38 +0000 (19:07 +0000)
committerDaniel Gruno <humbedooh@apache.org>
Sun, 29 Jul 2012 19:07:38 +0000 (19:07 +0000)
This might need some tweaking on the hash key generation for the mtime lookups, ideas are welcome.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1366890 13f79535-47bb-0310-9956-ffa450edef68

modules/lua/lua_vmprep.c
modules/lua/lua_vmprep.h
modules/lua/mod_lua.c
modules/lua/mod_lua.h

index e821fee3d16bb5bc9241712353bb38ecff0f8241..21fbf2073497e64c5e230656918108c69f169d03 100644 (file)
@@ -341,7 +341,7 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
                                                ap_lua_vm_spec *spec)
 {
     lua_State *L = NULL;
-
+    int tryCache = 0;
     if (apr_pool_userdata_get((void **)&L, spec->file,
                               lifecycle_pool) == APR_SUCCESS) {
       
@@ -360,6 +360,43 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
       }
     }
         /*}*/
-
+    if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
+        tryCache = 1;
+    }
+    else if (spec->codecache == AP_LUA_CACHE_STAT) {
+        apr_time_t modified;
+        char* mkey = apr_psprintf(lifecycle_pool, "ap_lua_modified:%s", spec->file);
+        if (apr_pool_userdata_get((void **)&modified, mkey,
+                              lifecycle_pool) == APR_SUCCESS) {
+            apr_finfo_t lua_finfo;
+            apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME, lifecycle_pool);
+            
+            /* On first visit, modified will be zero, but that's fine - The file is 
+             loaded in the vm_construct function.
+             */
+            if (modified == lua_finfo.mtime || modified == 0) tryCache = 1;
+            modified = lua_finfo.mtime;
+        }
+        else {
+            tryCache = 1;
+        }
+        apr_pool_userdata_set((void*) modified, mkey, NULL, lifecycle_pool);
+    }
+    if (tryCache == 0) {
+        int rc;
+        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01481)
+            "(re)loading lua file %s", spec->file);
+        rc = luaL_loadfile(L, spec->file);
+        if (rc != 0) {
+            ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(01482)
+                          "Error loading %s: %s", spec->file,
+                          rc == LUA_ERRMEM ? "memory allocation error"
+                                           : lua_tostring(L, 0));
+            return 0;
+        }
+        lua_pcall(L, 0, LUA_MULTRET, 0);
+    }
+    
+    
     return L;
 }
index 1d3758ca8e70de39ba6e9b35324528df0b34d7c3..c3b5376664d497ba34d7de68705fc0ea9f52453a 100644 (file)
 #define AP_LUA_SCOPE_CONN          3
 #define AP_LUA_SCOPE_THREAD        4
 
+#define AP_LUA_CACHE_UNSET         0
+#define AP_LUA_CACHE_NEVER         1
+#define AP_LUA_CACHE_STAT          2
+#define AP_LUA_CACHE_FOREVER       3
+
 
 typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
                                              void *ctx);
@@ -71,6 +76,8 @@ typedef struct
      */
     const char *bytecode;
     apr_size_t bytecode_len;
+    
+    int codecache;
 } ap_lua_vm_spec;
 
 typedef struct
@@ -81,6 +88,7 @@ typedef struct
     ap_regex_t *uri_pattern;
     const char *bytecode;
     apr_size_t bytecode_len;
+    int codecache;
 } ap_lua_mapped_handler_spec;
 
 /* remove and make static once out of mod_wombat.c */
index cb28137d66365bdecd4abf17de2db01224bd8b62..3881f532d897eafe9353ce19b4e6e81ddd8ba364 100644 (file)
@@ -130,6 +130,7 @@ static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
     spec->cb_arg = NULL;
     spec->bytecode = bytecode;
     spec->bytecode_len = bytecode_len;
+    spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache;
 
     if (filename) {
         char *file;
@@ -910,6 +911,29 @@ static const char *register_lua_inherit(cmd_parms *cmd,
     }
     return NULL;
 }
+static const char *register_lua_codecache(cmd_parms *cmd, 
+                                      void *_cfg,
+                                      const char *arg)
+{
+    ap_lua_dir_cfg *cfg = (ap_lua_dir_cfg *) _cfg;
+    
+    if (strcasecmp("never", arg) == 0) {
+        cfg->codecache = AP_LUA_CACHE_NEVER;
+    }
+    else if (strcasecmp("stat", arg) == 0) {
+        cfg->codecache = AP_LUA_CACHE_STAT;
+    }
+    else if (strcasecmp("forever", arg) == 0) {
+        cfg->codecache = AP_LUA_CACHE_FOREVER;
+    }
+    else { 
+        return apr_psprintf(cmd->pool,
+                            "LuaCodeCache type of '%s' not recognized, valid "
+                            "options are 'never', 'stat', and 'forever'", 
+                            arg);
+    }
+    return NULL;
+}
 static const char *register_lua_scope(cmd_parms *cmd, 
                                       void *_cfg,
                                       const char *scope, 
@@ -1184,6 +1208,10 @@ command_rec lua_commands[] = {
     AP_INIT_TAKE1("LuaInherit", register_lua_inherit, NULL, OR_ALL,
      "Controls how Lua scripts in parent contexts are merged with the current " 
      " context: none|parent-last|parent-first (default: parent-first) "),
+    
+    AP_INIT_TAKE1("LuaCodeCache", register_lua_codecache, NULL, OR_ALL,
+     "Controls the behavior of the in-memory code cache " 
+     " context: stat|forever|never (default: stat) "),
 
     AP_INIT_TAKE2("LuaQuickHandler", register_quick_hook, NULL, OR_ALL,
                   "Provide a hook for the quick handler of request processing"),
@@ -1270,6 +1298,7 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *overridesv)
 
     a->vm_scope = (overrides->vm_scope == AP_LUA_SCOPE_UNSET) ? base->vm_scope: overrides->vm_scope;
     a->inherit = (overrides->inherit== AP_LUA_INHERIT_UNSET) ? base->inherit : overrides->inherit;
+    a->codecache = (overrides->codecache== AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache;
 
     if (a->inherit == AP_LUA_INHERIT_UNSET || a->inherit == AP_LUA_INHERIT_PARENT_FIRST) { 
         a->package_paths = apr_array_append(p, base->package_paths, overrides->package_paths);
index 40add312908a7eb04aa60d8c13b1eaccdb212f4d..b737c0b672d05d95bc08fbbe49c7cf1f6d4cc68d 100644 (file)
@@ -120,6 +120,11 @@ typedef struct
   
     /* Whether Lua scripts in a sub-dir are run before parents */
     ap_lua_inherit_t inherit;
+    
+    /**
+     * AP_LUA_CACHE_NEVER | AP_LUA_CACHE_STAT | AP_LUA_CACHE_FOREVER
+     */
+    unsigned int codecache;
 
 } ap_lua_dir_cfg;