diff options
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | modules/lua/lua_request.c | 27 | ||||
-rw-r--r-- | modules/lua/lua_vmprep.c | 18 | ||||
-rw-r--r-- | modules/lua/mod_lua.c | 74 |
4 files changed, 105 insertions, 17 deletions
@@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_lua: Let the Inter-VM get/set functions work with a global + shared memory pool instead of a per-process pool. [Daniel Gruno] + *) WinNT MPM: Exit the child if the parent process crashes or is terminated. [Oracle Corporation] diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c index d8e62937d5..74f264315a 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -30,7 +30,8 @@ #include "util_cookies.h" #include "apr_want.h" -extern apr_thread_mutex_t* lua_ivm_mutex; +extern apr_global_mutex_t* lua_ivm_mutex; +extern apr_shm_t *lua_ivm_shm; APLOG_USE_MODULE(lua); #define POST_MAX_VARS 500 @@ -1831,21 +1832,23 @@ static int req_debug(lua_State *L) static int lua_ivm_get(lua_State *L) { const char *key, *raw_key; + apr_pool_t *pool; lua_ivm_object *object = NULL; request_rec *r = ap_lua_check_request_rec(L, 1); key = luaL_checkstring(L, 2); raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL); - apr_thread_mutex_lock(lua_ivm_mutex); - apr_pool_userdata_get((void **)&object, raw_key, r->server->process->pool); + apr_global_mutex_lock(lua_ivm_mutex); + pool = *((apr_pool_t**) apr_shm_baseaddr_get(lua_ivm_shm)); + apr_pool_userdata_get((void **)&object, raw_key, pool); if (object) { if (object->type == LUA_TBOOLEAN) lua_pushboolean(L, (int) object->number); else if (object->type == LUA_TNUMBER) lua_pushnumber(L, object->number); else if (object->type == LUA_TSTRING) lua_pushlstring(L, object->vb.buf, object->size); - apr_thread_mutex_unlock(lua_ivm_mutex); + apr_global_mutex_unlock(lua_ivm_mutex); return 1; } else { - apr_thread_mutex_unlock(lua_ivm_mutex); + apr_global_mutex_unlock(lua_ivm_mutex); return 0; } } @@ -1855,6 +1858,7 @@ static int lua_ivm_set(lua_State *L) { const char *key, *raw_key; const char *value = NULL; + apr_pool_t *pool; size_t str_len; lua_ivm_object *object = NULL; request_rec *r = ap_lua_check_request_rec(L, 1); @@ -1862,11 +1866,12 @@ static int lua_ivm_set(lua_State *L) luaL_checkany(L, 3); raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL); - apr_thread_mutex_lock(lua_ivm_mutex); - apr_pool_userdata_get((void **)&object, raw_key, r->server->process->pool); + apr_global_mutex_lock(lua_ivm_mutex); + pool = *((apr_pool_t**) apr_shm_baseaddr_get(lua_ivm_shm)); + apr_pool_userdata_get((void **)&object, raw_key, pool); if (!object) { - object = apr_pcalloc(r->server->process->pool, sizeof(lua_ivm_object)); - ap_varbuf_init(r->server->process->pool, &object->vb, 2); + object = apr_pcalloc(pool, sizeof(lua_ivm_object)); + ap_varbuf_init(pool, &object->vb, 2); object->size = 1; object->vb_size = 1; } @@ -1884,8 +1889,8 @@ static int lua_ivm_set(lua_State *L) memset(object->vb.buf, 0, str_len); memcpy(object->vb.buf, value, str_len-1); } - apr_pool_userdata_set(object, raw_key, NULL, r->server->process->pool); - apr_thread_mutex_unlock(lua_ivm_mutex); + apr_pool_userdata_set(object, raw_key, NULL, pool); + apr_global_mutex_unlock(lua_ivm_mutex); return 0; } diff --git a/modules/lua/lua_vmprep.c b/modules/lua/lua_vmprep.c index b0eb01c432..2bd0365f81 100644 --- a/modules/lua/lua_vmprep.c +++ b/modules/lua/lua_vmprep.c @@ -37,12 +37,28 @@ APLOG_USE_MODULE(lua); #if APR_HAS_THREADS apr_thread_mutex_t *ap_lua_mutex; +#endif +extern apr_global_mutex_t *lua_ivm_mutex; void ap_lua_init_mutex(apr_pool_t *pool, server_rec *s) { + apr_status_t rv; + + /* global IVM mutex */ + rv = apr_global_mutex_child_init(&lua_ivm_mutex, + apr_global_mutex_lockfile(lua_ivm_mutex), + pool); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, + "mod_lua: Failed to reopen mutex lua-ivm-shm in child"); + exit(1); /* bah :( */ + } + + /* Server pool mutex */ +#if APR_HAS_THREADS apr_thread_mutex_create(&ap_lua_mutex, APR_THREAD_MUTEX_DEFAULT, pool); -} #endif +} /* forward dec'l from this file */ diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c index 6e3390fbd2..cb3d6bcfdd 100644 --- a/modules/lua/mod_lua.c +++ b/modules/lua/mod_lua.c @@ -20,17 +20,32 @@ #include <stdlib.h> #include <ctype.h> #include <apr_thread_mutex.h> - +#include <apr_pools.h> #include "lua_apr.h" #include "lua_config.h" #include "apr_optional.h" #include "mod_ssl.h" #include "mod_auth.h" +#include "util_mutex.h" + #ifdef APR_HAS_THREADS #include "apr_thread_proc.h" #endif +/* getpid for *NIX */ +#if APR_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#if APR_HAVE_UNISTD_H +#include <unistd.h> +#endif + +/* getpid for Windows */ +#if APR_HAVE_PROCESS_H +#include <process.h> +#endif + APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap_lua, AP_LUA, int, lua_open, (lua_State *L, apr_pool_t *p), (L, p), OK, DECLINED) @@ -64,7 +79,16 @@ typedef struct int broken; } lua_filter_ctx; -apr_thread_mutex_t* lua_ivm_mutex = NULL; +apr_global_mutex_t *lua_ivm_mutex; +apr_shm_t *lua_ivm_shm; +char *lua_ivm_shmfile; + +static apr_status_t shm_cleanup_wrapper(void *unused) { + if (lua_ivm_shm) { + return apr_shm_destroy(lua_ivm_shm); + } + return OK; +} /** * error reporting if lua has an error. @@ -1916,11 +1940,53 @@ static int lua_request_hook(lua_State *L, request_rec *r) return OK; } +static int lua_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + ap_mutex_register(pconf, "lua-ivm-shm", NULL, APR_LOCK_DEFAULT, 0); + return OK; +} + static int lua_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { + apr_pool_t **pool; lua_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); lua_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https); + const char *tempdir; + apr_status_t rs; + + if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) + return OK; + + /* Create ivm mutex */ + rs = ap_global_mutex_create(&lua_ivm_mutex, NULL, "lua-ivm-shm", NULL, + s, pconf, 0); + if (APR_SUCCESS != rs) { + return HTTP_INTERNAL_SERVER_ERROR; + } + + /* Create shared memory space */ + rs = apr_temp_dir_get(&tempdir, pconf); + if (rs != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, + "mod_lua IVM: Failed to find temporary directory"); + return HTTP_INTERNAL_SERVER_ERROR; + } + lua_ivm_shmfile = apr_psprintf(pconf, "%s/httpd_lua_shm.%ld", tempdir, + (long int)getpid()); + rs = apr_shm_create(&lua_ivm_shm, sizeof(apr_pool_t**), + (const char *) lua_ivm_shmfile, pconf); + if (rs != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rs, s, + "mod_lua: Failed to create shared memory segment on file %s", + lua_ivm_shmfile); + return HTTP_INTERNAL_SERVER_ERROR; + } + pool = (apr_pool_t **)apr_shm_baseaddr_get(lua_ivm_shm); + apr_pool_create(pool, pconf); + apr_pool_cleanup_register(pconf, NULL, shm_cleanup_wrapper, + apr_pool_cleanup_null); return OK; } static void *overlay_hook_specs(apr_pool_t *p, @@ -2025,6 +2091,7 @@ static void lua_register_hooks(apr_pool_t *p) ap_hook_quick_handler(lua_quick_harness, NULL, NULL, APR_HOOK_FIRST); ap_hook_post_config(lua_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_config(lua_pre_config, NULL, NULL, APR_HOOK_MIDDLE); APR_OPTIONAL_HOOK(ap_lua, lua_open, lua_open_hook, NULL, NULL, APR_HOOK_REALLY_FIRST); @@ -2038,9 +2105,6 @@ static void lua_register_hooks(apr_pool_t *p) /* providers */ lua_authz_providers = apr_hash_make(p); - /* ivm mutex */ - apr_thread_mutex_create(&lua_ivm_mutex, APR_THREAD_MUTEX_DEFAULT, p); - /* Logging catcher */ ap_hook_log_transaction(lua_log_transaction_harness,NULL,NULL, APR_HOOK_FIRST); |