]> granicus.if.org Git - apache/commitdiff
Remove lua_ap_banner, as it's no longer being used.
authorDaniel Gruno <humbedooh@apache.org>
Fri, 19 Apr 2013 08:46:28 +0000 (08:46 +0000)
committerDaniel Gruno <humbedooh@apache.org>
Fri, 19 Apr 2013 08:46:28 +0000 (08:46 +0000)
Add ivm_get/ivm_set for Inter-VM data transfer. This allows multiple VMs across a process to share data without having to resort to external databases or filesystems. This is a work in progress, and I have yet to work out a proper way of resetting a variable without causing a memory leak (this could be done by allocating a new pool for each object, but I'm trying to see if there's a more efficient way). Comments, ideas etc are most welcome.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1469744 13f79535-47bb-0310-9956-ffa450edef68

docs/manual/mod/mod_lua.xml
modules/lua/lua_request.c
modules/lua/lua_request.h

index 203b9d246745db91dd5a1133a6e1ff1938fa6574..7765931aa40b45905b9fa1e0d69c6726d9e223e3 100644 (file)
@@ -889,6 +889,15 @@ r:dbacquire(dbType[, dbParams]) -- Acquires a connection to a database and retur
                         -- See '<a href="#databases">Database connectivity</a>' for details.
 </highlight>
 
+<highlight language="lua">
+r:ivm_set("key", value) -- Set an Inter-VM variable to hold a specific value.
+                        -- These values persist even though the VM is gone or not being used,
+                        -- and so should only be used if MaxConnectionsPerChild is > 0
+                        -- Values can be numbers, strings and booleans.
+                        
+r:ivm_get("key")        -- Fetches a variable set by ivm_set. Returns the contents of the variable
+                        -- if it exists or nil if no such variable exists.
+</highlight>
 
 </section>
 
index 4b57b9f8764f165dfdfeefbbeed7a13988d17066..34940ceeb5dae8944a54a355d3a50d91e1d3380e 100644 (file)
  * limitations under the License.
  */
 
+#include <lua.h>
+
+
+#include <apr_pools.h>
+
 #include "mod_lua.h"
 #include "util_script.h"
 #include "lua_apr.h"
@@ -33,6 +38,7 @@ typedef char *(*req_field_string_f) (request_rec * r);
 typedef int (*req_field_int_f) (request_rec * r);
 typedef apr_table_t *(*req_field_apr_table_f) (request_rec * r);
 
+
 void ap_lua_rstack_dump(lua_State *L, request_rec *r, const char *msg)
 {
     int i;
@@ -823,16 +829,6 @@ static int lua_apr_sha1(lua_State *L)
 }
 
 
-
-/*
- * lua_ap_banner; r:banner() - Returns the current server banner
- */
-static int lua_ap_banner(lua_State *L)
-{
-    lua_pushstring(L, ap_get_server_banner());
-    return 1;
-}
-
 /*
  * lua_ap_mpm_query; r:mpm_query(info) - Queries for MPM info
  */
@@ -1665,6 +1661,49 @@ static int req_debug(lua_State *L)
     return req_log_at(L, APLOG_DEBUG);
 }
 
+static int lua_ivm_get(lua_State *L) {
+    const char *key, *raw_key;
+    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_pool_userdata_get((void **)&object, raw_key, r->server->process->pool);
+    if (object) {
+        if (object->type == LUA_TBOOLEAN) lua_pushboolean(L, object->number);
+        else if (object->type == LUA_TBOOLEAN) lua_pushboolean(L, object->number);
+        else if (object->type == LUA_TNUMBER) lua_pushnumber(L, object->number);
+        else if (object->type == LUA_TSTRING) lua_pushlstring(L, object->string, object->size);
+        return 1;
+    }
+    else {
+        return 0;
+    }
+}
+
+
+static int lua_ivm_set(lua_State *L) {
+    const char *key, *raw_key;
+    const char *value = NULL;
+    lua_ivm_object *object = NULL;
+    request_rec *r = ap_lua_check_request_rec(L, 1);
+    key = luaL_checkstring(L, 2);
+    luaL_checkany(L, 3);
+    raw_key = apr_pstrcat(r->pool, "lua_ivm_", key, NULL);
+    
+    /* This will require MaxConnectionsPerChild to be > 0, since it's 
+     * essentially leaking memory as values are being overridden */
+    object = apr_pcalloc(r->server->process->pool, sizeof(lua_ivm_object));
+    object->type = lua_type(L, 3);
+    if (object->type == LUA_TNUMBER) object->number = lua_tonumber(L, 3);
+    else if (object->type == LUA_TBOOLEAN) object->number = lua_tonumber(L, 3);
+    else if (object->type == LUA_TSTRING) {
+        value = lua_tolstring(L, 3, &object->size);
+        object->string = apr_pstrmemdup(r->server->process->pool, value, object->size);
+    }
+    apr_pool_userdata_set(object, raw_key, NULL, r->server->process->pool);
+    return 0;
+}
+
 #define APLUA_REQ_TRACE(lev) static int req_trace##lev(lua_State *L)  \
 {                                                               \
     return req_log_at(L, APLOG_TRACE##lev);                     \
@@ -1770,6 +1809,8 @@ static const char* lua_ap_get_server_name(request_rec* r)
     return name ? name : "localhost";
 }
 
+
+
 static const struct luaL_Reg server_methods[] = {
     {NULL, NULL}
 };
@@ -1996,6 +2037,10 @@ AP_LUA_DECLARE(void) ap_lua_load_request_lmodule(lua_State *L, apr_pool_t *p)
                  makefun(&lua_ap_state_query, APL_REQ_FUNTYPE_LUACFUN, p));
     apr_hash_set(dispatch, "get_server_name_for_url", APR_HASH_KEY_STRING,
                  makefun(&lua_ap_get_server_name_for_url, APL_REQ_FUNTYPE_LUACFUN, p));
+    apr_hash_set(dispatch, "ivm_get", APR_HASH_KEY_STRING,
+                 makefun(&lua_ivm_get, APL_REQ_FUNTYPE_LUACFUN, p));
+    apr_hash_set(dispatch, "ivm_set", APR_HASH_KEY_STRING,
+                 makefun(&lua_ivm_set, APL_REQ_FUNTYPE_LUACFUN, p));
     
     lua_pushlightuserdata(L, dispatch);
     lua_setfield(L, LUA_REGISTRYINDEX, "Apache2.Request.dispatch");
index ad272dc98edfbc1c4891d50566cb73f77d99053e..460e2c18245ca143a7eca663baf72b550f2f230b 100644 (file)
@@ -37,5 +37,11 @@ typedef struct
     int type;
 } req_fun_t;
 
+typedef struct {
+    int type;
+    size_t size;
+    void* string;
+    lua_Number number;
+} lua_ivm_object;
 
 #endif /* !_LUA_REQUEST_H_ */