mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
apply patch from zhiguo zhao <zhaozg@gmail.com> to significantly improve server scope handling
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1081611 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -288,39 +288,30 @@ static int loadjitmodule(lua_State *L, apr_pool_t *lifecycle_pool) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
|
static apr_status_t vm_construct(void **vm, void *params, 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)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
lua_State* L;
|
lua_State* L;
|
||||||
|
|
||||||
if (!apr_pool_userdata_get((void **) &L, spec->file, lifecycle_pool)) {
|
ap_lua_vm_spec *spec = params;
|
||||||
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
|
#ifdef AP_ENABLE_LUAJIT
|
||||||
luaopen_jit(L);
|
luaopen_jit(L);
|
||||||
#endif
|
#endif
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
if (package_paths) {
|
if (spec->package_paths) {
|
||||||
munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool,
|
munge_path(L, "path", "?.lua", "./?.lua", lifecycle_pool,
|
||||||
package_paths, spec->file);
|
spec->package_paths, spec->file);
|
||||||
}
|
}
|
||||||
if (package_cpaths) {
|
if (spec->package_cpaths) {
|
||||||
munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
|
munge_path(L, "cpath", "?.so", "./?.so", lifecycle_pool,
|
||||||
package_cpaths, spec->file);
|
spec->package_cpaths, spec->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb) {
|
if (spec->cb) {
|
||||||
cb(L, lifecycle_pool, btn);
|
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) {
|
if (spec->bytecode && spec->bytecode_len > 0) {
|
||||||
luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
|
luaL_loadbuffer(L, spec->bytecode, spec->bytecode_len, spec->file);
|
||||||
@@ -350,7 +341,7 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
|
|||||||
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool,
|
ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool,
|
||||||
"Loading lua file %s: %s",
|
"Loading lua file %s: %s",
|
||||||
spec->file, err);
|
spec->file, err);
|
||||||
return NULL;
|
return APR_EBADF;
|
||||||
}
|
}
|
||||||
lua_pcall(L, 0, LUA_MULTRET, 0);
|
lua_pcall(L, 0, LUA_MULTRET, 0);
|
||||||
}
|
}
|
||||||
@@ -360,6 +351,79 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
|
|||||||
#endif
|
#endif
|
||||||
lua_pushlightuserdata(L, lifecycle_pool);
|
lua_pushlightuserdata(L, lifecycle_pool);
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Wombat.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;
|
return L;
|
||||||
|
@@ -43,6 +43,23 @@
|
|||||||
#define APL_SCOPE_CONN 3
|
#define APL_SCOPE_CONN 3
|
||||||
#define APL_SCOPE_SERVER 4
|
#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
|
* Specification for a lua virtual machine
|
||||||
*/
|
*/
|
||||||
@@ -61,7 +78,11 @@ typedef struct
|
|||||||
|
|
||||||
/* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_SERVER */
|
/* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_SERVER */
|
||||||
int scope;
|
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 */
|
/* pool to use for lifecycle if APL_SCOPE_ONCE is set, otherwise unused */
|
||||||
apr_pool_t *pool;
|
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);
|
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)
|
* alternate means of getting lua_State (preferred eventually)
|
||||||
* Obtain a lua_State which has loaded file and is associated with lifecycle_pool
|
* 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
|
* @ctx a baton passed to cb
|
||||||
*/
|
*/
|
||||||
AP_LUA_DECLARE(lua_State*) ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
|
AP_LUA_DECLARE(lua_State*) ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
|
||||||
ap_lua_vm_spec *spec,
|
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);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -121,9 +121,15 @@ static int lua_handler(request_rec *r)
|
|||||||
d = apr_palloc(r->pool, sizeof(mapped_request_details));
|
d = apr_palloc(r->pool, sizeof(mapped_request_details));
|
||||||
spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
|
spec = apr_pcalloc(r->pool, sizeof(ap_lua_vm_spec));
|
||||||
spec->scope = dcfg->vm_scope;
|
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->file = r->filename;
|
||||||
spec->code_cache_style = dcfg->code_cache_style;
|
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->spec = spec;
|
||||||
d->function_name = "handle";
|
d->function_name = "handle";
|
||||||
}
|
}
|
||||||
@@ -135,10 +141,7 @@ static int lua_handler(request_rec *r)
|
|||||||
d->spec->file,
|
d->spec->file,
|
||||||
d->function_name);
|
d->function_name);
|
||||||
L = ap_lua_get_lua_state(r->pool,
|
L = ap_lua_get_lua_state(r->pool,
|
||||||
d->spec,
|
d->spec);
|
||||||
cfg->package_paths,
|
|
||||||
cfg->package_cpaths,
|
|
||||||
&lua_open_callback, NULL);
|
|
||||||
|
|
||||||
if (!L) {
|
if (!L) {
|
||||||
/* TODO annotate spec with failure reason */
|
/* 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->file = hook_spec->file_name;
|
||||||
spec->code_cache_style = hook_spec->code_cache_style;
|
spec->code_cache_style = hook_spec->code_cache_style;
|
||||||
spec->scope = hook_spec->scope;
|
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 = hook_spec->bytecode;
|
||||||
spec->bytecode_len = hook_spec->bytecode_len;
|
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,
|
apr_filepath_merge(&spec->file, server_cfg->root_path,
|
||||||
spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
|
spec->file, APR_FILEPATH_NOTRELATIVE, r->pool);
|
||||||
L = ap_lua_get_lua_state(r->pool,
|
L = ap_lua_get_lua_state(r->pool,
|
||||||
spec,
|
spec);
|
||||||
cfg->package_paths,
|
|
||||||
cfg->package_cpaths,
|
|
||||||
&lua_open_callback, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user