1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-05 16:55:50 +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:
Brian McCallister
2011-03-14 23:43:23 +00:00
parent 2e3c696eb4
commit 2fed37e78a
3 changed files with 150 additions and 79 deletions

View 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;

View File

@@ -43,6 +43,23 @@
#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);

View 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);