1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Add a server scope for Lua states (in LuaScope), which creates a pool of states with manageable minimum and maximum size.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1369656 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Daniel Gruno
2012-08-05 19:57:44 +00:00
parent 7ab70fec3d
commit b598e862d3
4 changed files with 213 additions and 41 deletions

View File

@@ -23,6 +23,15 @@
APLOG_USE_MODULE(lua); APLOG_USE_MODULE(lua);
#if APR_HAS_THREADS
apr_thread_mutex_t *ap_lua_mutex;
void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s)
{
apr_thread_mutex_create(&ap_lua_mutex, APR_THREAD_MUTEX_DEFAULT, pool);
}
#endif
/* forward dec'l from this file */ /* forward dec'l from this file */
#if 0 #if 0
@@ -201,6 +210,16 @@ static apr_status_t cleanup_lua(void *l)
return APR_SUCCESS; return APR_SUCCESS;
} }
static apr_status_t server_cleanup_lua(void *resource)
{
ap_lua_server_spec* spec = (ap_lua_server_spec*) resource;
AP_DEBUG_ASSERT(spec != NULL);
if (spec->L != NULL) {
lua_close((lua_State *) spec->L);
}
return APR_SUCCESS;
}
/* /*
munge_path(L, munge_path(L,
"path", "path",
@@ -333,6 +352,39 @@ static apr_status_t vm_construct(lua_State **vm, void *params, apr_pool_t *lifec
return APR_SUCCESS; return APR_SUCCESS;
} }
ap_lua_vm_spec* copy_vm_spec(apr_pool_t* pool, ap_lua_vm_spec* spec)
{
ap_lua_vm_spec* copied_spec = apr_pcalloc(pool, sizeof(ap_lua_vm_spec));
copied_spec->bytecode_len = spec->bytecode_len;
copied_spec->bytecode = spec->bytecode ? apr_pstrdup(pool, spec->bytecode) : 0;
copied_spec->cb = spec->cb;
copied_spec->cb_arg = NULL;
copied_spec->file = spec->file ? apr_pstrdup(pool, spec->file) : 0;
copied_spec->package_cpaths = apr_array_copy(pool, spec->package_cpaths);
copied_spec->package_paths = apr_array_copy(pool, spec->package_paths);
copied_spec->pool = pool;
copied_spec->scope = AP_LUA_SCOPE_SERVER;
copied_spec->codecache = spec->codecache;
return copied_spec;
}
static apr_status_t server_vm_construct(lua_State **resource, void *params, apr_pool_t *pool)
{
lua_State* L;
ap_lua_server_spec* spec = apr_pcalloc(pool, sizeof(ap_lua_server_spec));
if (vm_construct(&L, params, pool) == APR_SUCCESS) {
spec->finfo = apr_pcalloc(pool, sizeof(ap_lua_finfo));
if (L != NULL) {
spec->L = L;
*resource = (void*) spec;
lua_pushlightuserdata(L, spec);
lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
return APR_SUCCESS;
}
}
return APR_EGENERAL;
}
/** /**
* Function used to create a lua_State instance bound into the web * Function used to create a lua_State instance bound into the web
* server in the appropriate scope. * server in the appropriate scope.
@@ -341,57 +393,96 @@ AP_LUA_DECLARE(lua_State*)ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
ap_lua_vm_spec *spec, request_rec* r) ap_lua_vm_spec *spec, request_rec* r)
{ {
lua_State *L = NULL; lua_State *L = NULL;
ap_lua_finfo *cache_info;
int tryCache = 0; int tryCache = 0;
if (apr_pool_userdata_get((void **)&L, spec->file,
lifecycle_pool) == APR_SUCCESS) {
if(L==NULL) { if (spec->scope == AP_LUA_SCOPE_SERVER) {
char *hash;
apr_reslist_t* reslist = NULL;
ap_lua_server_spec* sspec = NULL;
hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
#if APR_HAS_THREADS
apr_thread_mutex_lock(ap_lua_mutex);
#endif
if (apr_pool_userdata_get((void **)&reslist, hash,
r->server->process->pool) == APR_SUCCESS) {
if (reslist != NULL) {
if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
L = sspec->L;
cache_info = sspec->finfo;
}
}
}
if (L == NULL) {
ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec);
apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0,
(apr_reslist_constructor) server_vm_construct,
(apr_reslist_destructor) server_cleanup_lua,
server_spec, r->server->process->pool);
apr_pool_userdata_set(reslist, hash, NULL,
r->server->process->pool);
if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
L = sspec->L;
cache_info = sspec->finfo;
}
}
#if APR_HAS_THREADS
apr_thread_mutex_unlock(ap_lua_mutex);
#endif
}
else {
if (apr_pool_userdata_get((void **)&L, spec->file,
lifecycle_pool) != APR_SUCCESS) {
L = NULL;
}
}
if(L==NULL) {
ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483) ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
"creating lua_State with file %s", spec->file); "creating lua_State with file %s", spec->file);
/* not available, so create */ /* not available, so create */
if(!vm_construct(&L, spec, lifecycle_pool)) { if(!vm_construct(&L, spec, lifecycle_pool)) {
AP_DEBUG_ASSERT(L != NULL); AP_DEBUG_ASSERT(L != NULL);
apr_pool_userdata_set(L, apr_pool_userdata_set(L,
spec->file, spec->file,
cleanup_lua, cleanup_lua,
lifecycle_pool); lifecycle_pool);
} }
}
} }
/*}*/
if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) { if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
tryCache = 1; tryCache = 1;
} }
else { else {
ap_lua_finfo *cache_info; char* mkey;
char* mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file); if (spec->scope != AP_LUA_SCOPE_SERVER) {
if (apr_pool_userdata_get((void **)&cache_info, mkey, mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file);
lifecycle_pool) == APR_SUCCESS) { apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool);
if (cache_info == NULL) { if (cache_info == NULL) {
cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo)); cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo));
} }
if (spec->codecache == AP_LUA_CACHE_STAT) { }
apr_finfo_t lua_finfo; if (spec->codecache == AP_LUA_CACHE_STAT) {
apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool); apr_finfo_t lua_finfo;
apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool);
/* On first visit, modified will be zero, but that's fine - The file is /* On first visit, modified will be zero, but that's fine - The file is
loaded in the vm_construct function. loaded in the vm_construct function.
*/ */
if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size) \ if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size) \
|| cache_info->modified == 0) tryCache = 1; || cache_info->modified == 0) {
cache_info->modified = lua_finfo.mtime; tryCache = 1;
cache_info->size = lua_finfo.size;
} }
else if (spec->codecache == AP_LUA_CACHE_NEVER) { cache_info->modified = lua_finfo.mtime;
if (cache_info->runs == 0) tryCache = 1; cache_info->size = lua_finfo.size;
}
cache_info->runs++;
} }
else { else if (spec->codecache == AP_LUA_CACHE_NEVER) {
tryCache = 1; if (cache_info->runs == 0) tryCache = 1;
}
cache_info->runs++;
if (spec->scope != AP_LUA_SCOPE_SERVER) {
apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
} }
apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
} }
if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) { if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) {
int rc; int rc;

View File

@@ -29,6 +29,7 @@
#include "apr_file_info.h" #include "apr_file_info.h"
#include "apr_time.h" #include "apr_time.h"
#include "apr_pools.h" #include "apr_pools.h"
#include "apr_reslist.h"
#ifndef VMPREP_H #ifndef VMPREP_H
@@ -39,16 +40,15 @@
#define AP_LUA_SCOPE_REQUEST 2 #define AP_LUA_SCOPE_REQUEST 2
#define AP_LUA_SCOPE_CONN 3 #define AP_LUA_SCOPE_CONN 3
#define AP_LUA_SCOPE_THREAD 4 #define AP_LUA_SCOPE_THREAD 4
#define AP_LUA_SCOPE_SERVER 5
#define AP_LUA_CACHE_UNSET 0 #define AP_LUA_CACHE_UNSET 0
#define AP_LUA_CACHE_NEVER 1 #define AP_LUA_CACHE_NEVER 1
#define AP_LUA_CACHE_STAT 2 #define AP_LUA_CACHE_STAT 2
#define AP_LUA_CACHE_FOREVER 3 #define AP_LUA_CACHE_FOREVER 3
typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p, typedef void (*ap_lua_state_open_callback) (lua_State *L, apr_pool_t *p,
void *ctx); void *ctx);
/** /**
* Specification for a lua virtual machine * Specification for a lua virtual machine
*/ */
@@ -61,8 +61,10 @@ typedef struct
/* name of base file to load in the vm */ /* name of base file to load in the vm */
const char *file; const char *file;
/* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_THREAD */ /* APL_SCOPE_ONCE | APL_SCOPE_REQUEST | APL_SCOPE_CONN | APL_SCOPE_THREAD | APL_SCOPE_SERVER */
int scope; int scope;
unsigned int vm_min;
unsigned int vm_max;
ap_lua_state_open_callback cb; ap_lua_state_open_callback cb;
void* cb_arg; void* cb_arg;
@@ -97,6 +99,11 @@ typedef struct {
apr_size_t size; apr_size_t size;
} ap_lua_finfo; } ap_lua_finfo;
typedef struct {
lua_State* L;
ap_lua_finfo* finfo;
} ap_lua_server_spec;
/* remove and make static once out of mod_wombat.c */ /* remove and make static once out of mod_wombat.c */
AP_LUA_DECLARE(void) ap_lua_openlibs(lua_State *L); AP_LUA_DECLARE(void) ap_lua_openlibs(lua_State *L);

View File

@@ -65,7 +65,6 @@ static void report_lua_error(lua_State *L, request_rec *r)
const char *lua_response; const char *lua_response;
r->status = HTTP_INTERNAL_SERVER_ERROR; r->status = HTTP_INTERNAL_SERVER_ERROR;
r->content_type = "text/html"; r->content_type = "text/html";
ap_rputs("<b>Error!</b>\n", r); ap_rputs("<b>Error!</b>\n", r);
ap_rputs("<p>", r); ap_rputs("<p>", r);
lua_response = lua_tostring(L, -1); lua_response = lua_tostring(L, -1);
@@ -109,6 +108,29 @@ static const char *scope_to_string(unsigned int scope)
} }
} }
static void ap_lua_release_state(lua_State* L, ap_lua_vm_spec* spec, request_rec* r) {
char *hash;
apr_reslist_t* reslist = NULL;
if (spec->scope == AP_LUA_SCOPE_SERVER) {
ap_lua_server_spec* sspec = NULL;
lua_settop(L, 0);
lua_getfield(L, LUA_REGISTRYINDEX, "Apache2.Lua.server_spec");
sspec = (ap_lua_server_spec*) lua_touserdata(L, 1);
hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
if (apr_pool_userdata_get((void **)&reslist, hash,
r->server->process->pool) == APR_SUCCESS) {
AP_DEBUG_ASSERT(sspec != NULL);
if (reslist != NULL) {
apr_reslist_release(reslist, sspec);
}
}
}
}
#if APR_HAS_THREADS
extern void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s);
#endif
static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool, static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
request_rec *r, request_rec *r,
const ap_lua_dir_cfg *cfg, const ap_lua_dir_cfg *cfg,
@@ -131,6 +153,8 @@ static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
spec->bytecode = bytecode; spec->bytecode = bytecode;
spec->bytecode_len = bytecode_len; spec->bytecode_len = bytecode_len;
spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache; spec->codecache = (cfg->codecache == AP_LUA_CACHE_UNSET) ? AP_LUA_CACHE_STAT : cfg->codecache;
spec->vm_min = cfg->vm_min ? cfg->vm_min : 1;
spec->vm_max = cfg->vm_max ? cfg->vm_max : 1;
if (filename) { if (filename) {
char *file; char *file;
@@ -161,6 +185,9 @@ static ap_lua_vm_spec *create_vm_spec(apr_pool_t **lifecycle_pool,
case AP_LUA_SCOPE_THREAD: case AP_LUA_SCOPE_THREAD:
pool = apr_thread_pool_get(r->connection->current_thread); pool = apr_thread_pool_get(r->connection->current_thread);
break; break;
case AP_LUA_SCOPE_SERVER:
pool = r->server->process->pool;
break;
#endif #endif
default: default:
ap_assert(0); ap_assert(0);
@@ -230,6 +257,7 @@ static int lua_handler(request_rec *r)
/* TODO annotate spec with failure reason */ /* TODO annotate spec with failure reason */
r->status = HTTP_INTERNAL_SERVER_ERROR; r->status = HTTP_INTERNAL_SERVER_ERROR;
ap_rputs("Unable to compile VM, see logs", r); ap_rputs("Unable to compile VM, see logs", r);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, APLOGNO(01474) "got a vm!"); ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, APLOGNO(01474) "got a vm!");
@@ -239,12 +267,14 @@ static int lua_handler(request_rec *r)
"lua: Unable to find function %s in %s", "lua: Unable to find function %s in %s",
"handle", "handle",
spec->file); spec->file);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
ap_lua_run_lua_request(L, r); ap_lua_run_lua_request(L, r);
if (lua_pcall(L, 1, 0, 0)) { if (lua_pcall(L, 1, 0, 0)) {
report_lua_error(L, r); report_lua_error(L, r);
} }
ap_lua_release_state(L, spec, r);
} }
return OK; return OK;
} }
@@ -300,6 +330,7 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
"lua: Unable to find function %s in %s", "lua: Unable to find function %s in %s",
hook_spec->function_name, hook_spec->function_name,
hook_spec->file_name); hook_spec->file_name);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
@@ -316,6 +347,7 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
if (lua_pcall(L, 1, 1, 0)) { if (lua_pcall(L, 1, 1, 0)) {
report_lua_error(L, r); report_lua_error(L, r);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
rc = DECLINED; rc = DECLINED;
@@ -323,6 +355,7 @@ static int lua_request_rec_hook_harness(request_rec *r, const char *name, int ap
rc = lua_tointeger(L, -1); rc = lua_tointeger(L, -1);
} }
if (rc != DECLINED) { if (rc != DECLINED) {
ap_lua_release_state(L, spec, r);
return rc; return rc;
} }
} }
@@ -373,6 +406,7 @@ static int lua_map_handler(request_rec *r)
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01477) ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01477)
"lua: Failed to obtain lua interpreter for %s %s", "lua: Failed to obtain lua interpreter for %s %s",
function_name, filename); function_name, filename);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
@@ -383,6 +417,7 @@ static int lua_map_handler(request_rec *r)
"lua: Unable to find function %s in %s", "lua: Unable to find function %s in %s",
function_name, function_name,
filename); filename);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
@@ -399,6 +434,7 @@ static int lua_map_handler(request_rec *r)
if (lua_pcall(L, 1, 1, 0)) { if (lua_pcall(L, 1, 1, 0)) {
report_lua_error(L, r); report_lua_error(L, r);
ap_lua_release_state(L, spec, r);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
rc = DECLINED; rc = DECLINED;
@@ -406,6 +442,7 @@ static int lua_map_handler(request_rec *r)
rc = lua_tointeger(L, -1); rc = lua_tointeger(L, -1);
} }
if (rc != DECLINED) { if (rc != DECLINED) {
ap_lua_release_state(L, spec, r);
return rc; return rc;
} }
} }
@@ -1110,12 +1147,33 @@ static const char *register_lua_scope(cmd_parms *cmd,
#endif #endif
cfg->vm_scope = AP_LUA_SCOPE_THREAD; cfg->vm_scope = AP_LUA_SCOPE_THREAD;
} }
else if (strcmp("server", scope) == 0) {
unsigned int vmin, vmax;
#if !APR_HAS_THREADS
return apr_psprintf(cmd->pool,
"Scope type of '%s' cannot be used because this "
"server does not have threading support "
"(APR_HAS_THREADS)"
scope);
#endif
cfg->vm_scope = AP_LUA_SCOPE_SERVER;
vmin = min ? atoi(min) : 1;
vmax = max ? atoi(max) : 1;
if (vmin == 0) {
vmin = 1;
}
if (vmax < vmin) {
vmax = vmin;
}
cfg->vm_min = vmin;
cfg->vm_max = vmax;
}
else { else {
return apr_psprintf(cmd->pool, return apr_psprintf(cmd->pool,
"Invalid value for LuaScope, '%s', acceptable " "Invalid value for LuaScope, '%s', acceptable "
"values are: 'once', 'request', 'conn', 'server'" "values are: 'once', 'request', 'conn'"
#if APR_HAS_THREADS #if APR_HAS_THREADS
", 'thread'" ", 'thread', 'server'"
#endif #endif
,scope); ,scope);
} }
@@ -1203,6 +1261,7 @@ static authz_status lua_authz_check(request_rec *r, const char *require_line,
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02319) ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(02319)
"Unable to find function %s in %s", "Unable to find function %s in %s",
prov_spec->function_name, prov_spec->file_name); prov_spec->function_name, prov_spec->file_name);
ap_lua_release_state(L, spec, r);
return AUTHZ_GENERAL_ERROR; return AUTHZ_GENERAL_ERROR;
} }
ap_lua_run_lua_request(L, r); ap_lua_run_lua_request(L, r);
@@ -1211,6 +1270,7 @@ static authz_status lua_authz_check(request_rec *r, const char *require_line,
if (!lua_checkstack(L, prov_spec->args->nelts)) { if (!lua_checkstack(L, prov_spec->args->nelts)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02315)
"Error: authz provider %s: too many arguments", prov_spec->name); "Error: authz provider %s: too many arguments", prov_spec->name);
ap_lua_release_state(L, spec, r);
return AUTHZ_GENERAL_ERROR; return AUTHZ_GENERAL_ERROR;
} }
for (i = 0; i < prov_spec->args->nelts; i++) { for (i = 0; i < prov_spec->args->nelts; i++) {
@@ -1223,14 +1283,17 @@ static authz_status lua_authz_check(request_rec *r, const char *require_line,
const char *err = lua_tostring(L, -1); const char *err = lua_tostring(L, -1);
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02316) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02316)
"Error executing authz provider %s: %s", prov_spec->name, err); "Error executing authz provider %s: %s", prov_spec->name, err);
ap_lua_release_state(L, spec, r);
return AUTHZ_GENERAL_ERROR; return AUTHZ_GENERAL_ERROR;
} }
if (!lua_isnumber(L, -1)) { if (!lua_isnumber(L, -1)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02317) ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02317)
"Error: authz provider %s did not return integer", prov_spec->name); "Error: authz provider %s did not return integer", prov_spec->name);
ap_lua_release_state(L, spec, r);
return AUTHZ_GENERAL_ERROR; return AUTHZ_GENERAL_ERROR;
} }
result = lua_tointeger(L, -1); result = lua_tointeger(L, -1);
ap_lua_release_state(L, spec, r);
switch (result) { switch (result) {
case AUTHZ_DENIED: case AUTHZ_DENIED:
case AUTHZ_GRANTED: case AUTHZ_GRANTED:
@@ -1389,6 +1452,8 @@ static void *create_dir_config(apr_pool_t *p, char *dir)
cfg->dir = apr_pstrdup(p, dir); cfg->dir = apr_pstrdup(p, dir);
cfg->vm_scope = AP_LUA_SCOPE_UNSET; cfg->vm_scope = AP_LUA_SCOPE_UNSET;
cfg->codecache = AP_LUA_CACHE_UNSET; cfg->codecache = AP_LUA_CACHE_UNSET;
cfg->vm_min = 0;
cfg->vm_max = 0;
return cfg; return cfg;
} }
@@ -1453,6 +1518,9 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *overridesv)
a->inherit = (overrides->inherit== AP_LUA_INHERIT_UNSET) ? base->inherit : overrides->inherit; a->inherit = (overrides->inherit== AP_LUA_INHERIT_UNSET) ? base->inherit : overrides->inherit;
a->codecache = (overrides->codecache== AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache; a->codecache = (overrides->codecache== AP_LUA_CACHE_UNSET) ? base->codecache : overrides->codecache;
a->vm_min = (overrides->vm_min== 0) ? base->vm_min : overrides->vm_min;
a->vm_max = (overrides->vm_max== 0) ? base->vm_max : overrides->vm_max;
if (a->inherit == AP_LUA_INHERIT_UNSET || a->inherit == AP_LUA_INHERIT_PARENT_FIRST) { 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); a->package_paths = apr_array_append(p, base->package_paths, overrides->package_paths);
a->package_cpaths = apr_array_append(p, base->package_cpaths, overrides->package_cpaths); a->package_cpaths = apr_array_append(p, base->package_cpaths, overrides->package_cpaths);
@@ -1529,6 +1597,9 @@ static void lua_register_hooks(apr_pool_t *p)
APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL, APR_OPTIONAL_HOOK(ap_lua, lua_request, lua_request_hook, NULL, NULL,
APR_HOOK_REALLY_FIRST); APR_HOOK_REALLY_FIRST);
ap_hook_handler(lua_map_handler, NULL, NULL, AP_LUA_HOOK_FIRST); ap_hook_handler(lua_map_handler, NULL, NULL, AP_LUA_HOOK_FIRST);
#if APR_HAS_THREADS
ap_hook_child_init(ap_lua_init_mutex, NULL, NULL, APR_HOOK_MIDDLE);
#endif
/* providers */ /* providers */
lua_authz_providers = apr_hash_make(p); lua_authz_providers = apr_hash_make(p);
} }

View File

@@ -39,6 +39,7 @@
#include "apr_file_info.h" #include "apr_file_info.h"
#include "apr_time.h" #include "apr_time.h"
#include "apr_hooks.h" #include "apr_hooks.h"
#include "apr_reslist.h"
/* Allow for Lua 5.2 backwards compatibility */ /* Allow for Lua 5.2 backwards compatibility */
#define LUA_COMPAT_ALL #define LUA_COMPAT_ALL
@@ -111,6 +112,8 @@ typedef struct
* AP_LUA_SCOPE_ONCE | AP_LUA_SCOPE_REQUEST | AP_LUA_SCOPE_CONN | AP_LUA_SCOPE_SERVER * AP_LUA_SCOPE_ONCE | AP_LUA_SCOPE_REQUEST | AP_LUA_SCOPE_CONN | AP_LUA_SCOPE_SERVER
*/ */
unsigned int vm_scope; unsigned int vm_scope;
unsigned int vm_min;
unsigned int vm_max;
/* info for the hook harnesses */ /* info for the hook harnesses */
apr_hash_t *hooks; /* <wombat_hook_info> */ apr_hash_t *hooks; /* <wombat_hook_info> */