]> granicus.if.org Git - apache/commitdiff
apply patch from zhiguo zhao <zhaozg@gmail.com> to significantly improve server scope...
authorBrian McCallister <brianm@apache.org>
Mon, 14 Mar 2011 23:43:23 +0000 (23:43 +0000)
committerBrian McCallister <brianm@apache.org>
Mon, 14 Mar 2011 23:43:23 +0000 (23:43 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1081611 13f79535-47bb-0310-9956-ffa450edef68

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

index 786d52984105bc6dc87613b4a4c11143f02a3060..7373e0f91f9995a88684022dc3fad71bad210e8f 100644 (file)
@@ -288,52 +288,43 @@ static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
 
 #endif
 
-AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
-                                               ap_lua_vm_spec *spec,
-                                               apr_array_header_t *package_paths,
-                                               apr_array_header_t *package_cpaths,
-                                               ap_lua_state_open_callback cb,
-                                               void *btn)
+static apr_status_t vm_construct(void **vm, void *params, apr_pool_t *lifecycle_pool)
 {
+    lua_State* L;
+    
+    ap_lua_vm_spec *spec = params;
 
-    lua_State *L;
-
-    if (!apr_pool_userdata_get((void **) &L, spec->file, lifecycle_pool)) {
-        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
-                      "creating lua_State with file %s", spec->file);
-        /* not available, so create */
-        L = luaL_newstate();
+    L = luaL_newstate();
 #ifdef AP_ENABLE_LUAJIT
-        luaopen_jit(L);
+    luaopen_jit(L);
 #endif
-        luaL_openlibs(L);
-        if (package_paths) {
-            munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool,
-                       package_paths, spec->file);
-        }
-        if (package_cpaths) {
-            munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
-                       package_cpaths, spec->file);
-        }
+    luaL_openlibs(L);
+    if (spec->package_paths) {
+        munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool,
+            spec->package_paths, spec->file);
+    }
+    if (spec->package_cpaths) {
+        munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
+            spec->package_cpaths, spec->file);
+    }
 
-        if (cb) {
-            cb(L, lifecycle_pool, btn);
-        }
+    if (spec->cb) {
+        spec->cb(L, lifecycle_pool, spec->cb_arg);
+    }
 
-        apr_pool_userdata_set(L, spec->file, &cleanup_lua, lifecycle_pool);
 
-        if (spec->bytecode && spec->bytecode_len > 0) {
-            luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
-            lua_pcall(L, 0, LUA_MULTRET, 0);
-        }
-        else {
-            int rc;
-            ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
-                          "loading lua file %s", spec->file);
-            rc = luaL_loadfile(L, spec->file);
-            if (rc != 0) {
-                char *err;
-                switch (rc) {
+    if (spec->bytecode && spec->bytecode_len > 0) {
+        luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
+        lua_pcall(L, 0, LUA_MULTRET, 0);
+    }
+    else {
+        int rc;
+        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
+            "loading lua file %s", spec->file);
+        rc = luaL_loadfile(L, spec->file);
+        if (rc != 0) {
+            char *err;
+            switch (rc) {
                 case LUA_ERRSYNTAX: 
                     err = "syntax error"; 
                     break;
@@ -346,20 +337,93 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
                 default:
                     err = "unknown error"; 
                     break;
-                }
-                ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool,
-                              "Loading lua file %s: %s",
-                              spec->file, err);
-                return NULL;
             }
-            lua_pcall(L, 0, LUA_MULTRET, 0);
+            ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool,
+                "Loading lua file %s: %s",
+                spec->file, err);
+            return APR_EBADF;
         }
+        lua_pcall(L, 0, LUA_MULTRET, 0);
+    }
 
 #ifdef AP_ENABLE_LUAJIT
-        loadjitmodule(L, lifecycle_pool);
+    loadjitmodule(L, lifecycle_pool);
 #endif
-        lua_pushlightuserdata(L, lifecycle_pool);
-        lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
+    lua_pushlightuserdata(L, lifecycle_pool);
+    lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.pool");
+    *vm = L;
+
+    return APR_SUCCESS;
+}
+
+static apr_status_t vm_destruct(void *vm, void *params, apr_pool_t *pool)
+{
+    lua_State *L = (lua_State *)vm; 
+
+    (void*)params;
+    (void*)pool;
+
+    cleanup_lua(L);
+
+    return APR_SUCCESS;
+}
+
+static apr_status_t vm_release(lua_State* vm)
+{
+    apr_reslist_t* reslist;
+    lua_pushlightuserdata(vm,vm);
+    lua_rawget(vm,LUA_REGISTRYINDEX);
+    reslist = (apr_reslist_t*)lua_topointer(vm,-1);
+
+    return apr_reslist_release(reslist, vm);
+}
+
+static apr_status_t vm_reslist_destroy(void *data)
+{
+    return apr_reslist_destroy(data);
+}
+
+AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
+                                               ap_lua_vm_spec *spec)
+{
+    lua_State *L = NULL;
+
+    if (spec->scope == APL_SCOPE_SERVER) {
+        apr_reslist_t *reslist;
+
+        if (apr_pool_userdata_get(&reslist,"mod_lua",spec->pool)==APR_SUCCESS) {
+            if(reslist==NULL) {
+                if(apr_reslist_create(&reslist, 
+                    spec->vm_server_pool_min, 
+                    spec->vm_server_pool_max,
+                    spec->vm_server_pool_max,
+                    0,
+                    vm_construct,
+                    vm_destruct,
+                    spec,
+                    spec->pool)!=APR_SUCCESS)
+                    return NULL;
+
+                apr_pool_userdata_set(reslist, "mod_lua", vm_reslist_destroy, spec->pool);
+            }
+            apr_reslist_acquire(reslist, &L);
+            lua_pushlightuserdata(L, L);
+            lua_pushlightuserdata(L, reslist);
+            lua_rawset(L,LUA_REGISTRYINDEX);
+            apr_pool_userdata_set(L, spec->file, vm_release, lifecycle_pool);
+        }
+    } else {
+        if (apr_pool_userdata_get((void **) &L, spec->file, lifecycle_pool)==APR_SUCCESS) {
+
+            if(L==NULL) {
+                ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool,
+                    "creating lua_State with file %s", spec->file);
+                /* not available, so create */
+
+                if(!vm_construct(&L, spec, lifecycle_pool))
+                    apr_pool_userdata_set(L, spec->file, &cleanup_lua, lifecycle_pool);
+            }
+        }
     }
 
     return L;
index 995ff2db0251a38ee6a92575b2fb4fb12ea4d6f9..ef0d629c1cbdcb40f529664a2f809dc56405723c 100644 (file)
 #define APL_SCOPE_CONN          3
 #define APL_SCOPE_SERVER        4
 
+
+/**
+ * the ap_lua_?getvm family of functions is used to create and/or obtain
+ * a handle to a lua state. If there is not an extant vm matching the
+ * spec then a new one is created.
+ */
+/* lua_State* ap_lua_rgetvm(request_rec *r, ap_lua_vm_spec *spec); */
+
+/* returns NULL if the spec requires a request scope */
+/* lua_State* ap_lua_cgetvm(conn_rec *r, ap_lua_vm_spec *spec);*/
+
+/* returns NULL if the spec requires a request scope or conn scope */
+/* lua_State* ap_lua_sgetvm(server_rec *r, ap_lua_vm_spec *spec); */
+
+typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
+                                             void *ctx);
+
 /**
  * Specification for a lua virtual machine
  */
@@ -61,7 +78,11 @@ typedef struct
 
     /* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_SERVER */
     int scope;
+       unsigned int vm_server_pool_min;
+       unsigned int vm_server_pool_max;
 
+       ap_lua_state_open_callback cb;
+       void* cb_arg;
     /* pool to use for lifecycle if APL_SCOPE_ONCE is set, otherwise unused */
     apr_pool_t *pool;
 
@@ -102,22 +123,6 @@ AP_LUA_DECLARE(void) ap_lua_registerlib(lua_State *L, char *name, lua_CFunction
  */
 AP_LUA_DECLARE(void) ap_lua_load_apache2_lmodule(lua_State *L);
 
-/**
- * the ap_lua_?getvm family of functions is used to create and/or obtain
- * a handle to a lua state. If there is not an extant vm matching the
- * spec then a new one is created.
- */
-/* lua_State* ap_lua_rgetvm(request_rec *r, ap_lua_vm_spec *spec); */
-
-/* returns NULL if the spec requires a request scope */
-/* lua_State* ap_lua_cgetvm(conn_rec *r, ap_lua_vm_spec *spec);*/
-
-/* returns NULL if the spec requires a request scope or conn scope */
-/* lua_State* ap_lua_sgetvm(server_rec *r, ap_lua_vm_spec *spec); */
-
-typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
-                                             void *ctx);
-
 /*
  * alternate means of getting lua_State (preferred eventually)
  * Obtain a lua_State which has loaded file and is associated with lifecycle_pool
@@ -131,11 +136,7 @@ typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
  * @ctx a baton passed to cb
  */
 AP_LUA_DECLARE(lua_State*) ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
-                                                ap_lua_vm_spec *spec,
-                                                apr_array_header_t *package_paths,
-                                                apr_array_header_t *package_cpaths,
-                                                ap_lua_state_open_callback cb, 
-                                                void *btn);
+                                                ap_lua_vm_spec *spec);
 
 
 
index cf41f35384fa30823028bdc409ed6dc09de44162..b1a23112d0be56b9b4f6b05302164be912f3db70 100644 (file)
@@ -121,9 +121,15 @@ static int lua_handler(request_rec *r)
             d = apr_palloc(r->pool, sizeof(mapped_request_details));
             spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
             spec->scope = dcfg->vm_scope;
-            spec->pool = r->pool;
+                       spec->pool = spec->scope==APL_SCOPE_SERVER ? cfg->pool : r->pool;
             spec->file = r->filename;
             spec->code_cache_style = dcfg->code_cache_style;
+                       spec->package_paths = cfg->package_paths;
+                       spec->package_cpaths = cfg->package_cpaths;
+                       spec->vm_server_pool_min = cfg->vm_server_pool_min;
+                       spec->vm_server_pool_max = cfg->vm_server_pool_max;
+                       spec->cb = &lua_open_callback;
+                       spec->cb_arg = NULL;
             d->spec = spec;
             d->function_name = "handle";
         }
@@ -135,10 +141,7 @@ static int lua_handler(request_rec *r)
                       d->spec->file,
                       d->function_name);
         L = ap_lua_get_lua_state(r->pool,
-                              d->spec,
-                              cfg->package_paths,
-                              cfg->package_cpaths,
-                              &lua_open_callback, NULL);
+                              d->spec);
 
         if (!L) {
             /* TODO annotate spec with failure reason */
@@ -246,17 +249,20 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name)
             spec->file = hook_spec->file_name;
             spec->code_cache_style = hook_spec->code_cache_style;
             spec->scope = hook_spec->scope;
+                       spec->vm_server_pool_min = cfg->vm_server_pool_min;
+                       spec->vm_server_pool_max = cfg->vm_server_pool_max;
             spec->bytecode = hook_spec->bytecode;
             spec->bytecode_len = hook_spec->bytecode_len;
-            spec->pool = r->pool;
+            spec->pool = spec->scope==APL_SCOPE_SERVER ? cfg->pool : r->pool;
+                       spec->package_paths = cfg->package_paths;
+                       spec->package_cpaths = cfg->package_cpaths;
+                       spec->cb = &lua_open_callback;
+                       spec->cb_arg = NULL;
 
             apr_filepath_merge(&spec->file, server_cfg->root_path,
                                spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
             L = ap_lua_get_lua_state(r->pool,
-                                  spec,
-                                  cfg->package_paths,
-                                  cfg->package_cpaths,
-                                  &lua_open_callback, NULL);
+                                  spec);