]> granicus.if.org Git - apache/commitdiff
mod_lua: Use a (new) global pool/mutex setup for IVM rather than a per-process pool.
authorDaniel Gruno <humbedooh@apache.org>
Fri, 27 Sep 2013 13:56:53 +0000 (13:56 +0000)
committerDaniel Gruno <humbedooh@apache.org>
Fri, 27 Sep 2013 13:56:53 +0000 (13:56 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1526906 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/lua/lua_request.c
modules/lua/lua_vmprep.c
modules/lua/mod_lua.c

diff --git a/CHANGES b/CHANGES
index 88c80a88c0249a6f04bf253461147a7b042ca2f3..8b37fbda47f34962899f3820a9b2e7bc19f26a6f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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]
 
index d8e62937d5b739977e1ed9f38553fd4edd7889df..74f264315ab5078c37305b3b42f5091fb4002068 100644 (file)
@@ -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;
 }
 
index b0eb01c432791adee7b30bcef825ae07d8d93e40..2bd0365f81f510c2fc86f6e47989c2711cd4f586 100644 (file)
@@ -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 */
 
index 6e3390fbd2f346668c4f655821ec0c10e2a66fca..cb3d6bcfdd2f88f6b873798e6c5cfe0ecbae6b72 100644 (file)
 #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);