You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by hu...@apache.org on 2013/04/20 14:26:07 UTC

svn commit: r1470156 - in /httpd/httpd/trunk/modules/lua: lua_request.c lua_request.h mod_lua.c

Author: humbedooh
Date: Sat Apr 20 12:26:05 2013
New Revision: 1470156

URL: http://svn.apache.org/r1470156
Log:
Use a mutex to control read/write for IVM values, so we can reuse the existing structures without running into race conditions.
This should get rid of the need to have MaxConnectionsPerChild set to > 0.

If a new value is set and is a string, we either use the existing varbuf or grow it accordingly.

Modified:
    httpd/httpd/trunk/modules/lua/lua_request.c
    httpd/httpd/trunk/modules/lua/lua_request.h
    httpd/httpd/trunk/modules/lua/mod_lua.c

Modified: httpd/httpd/trunk/modules/lua/lua_request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/lua/lua_request.c?rev=1470156&r1=1470155&r2=1470156&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/lua/lua_request.c (original)
+++ httpd/httpd/trunk/modules/lua/lua_request.c Sat Apr 20 12:26:05 2013
@@ -19,6 +19,7 @@
 
 
 #include <apr_pools.h>
+#include <apr_thread_mutex.h>
 
 #include "mod_lua.h"
 #include "util_script.h"
@@ -28,6 +29,8 @@
 #include "util_md5.h"
 #include "util_varbuf.h"
 
+extern apr_thread_mutex_t* lua_ivm_mutex;
+
 APLOG_USE_MODULE(lua);
 #define POST_MAX_VARS 500
 
@@ -1652,50 +1655,64 @@ static int req_debug(lua_State *L)
     return req_log_at(L, APLOG_DEBUG);
 }
 
-static int lua_ivm_get(lua_State *L) {
+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_thread_mutex_lock(lua_ivm_mutex);
     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_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);
         return 1;
     }
     else {
+        apr_thread_mutex_unlock(lua_ivm_mutex);
         return 0;
     }
 }
 
 
-static int lua_ivm_set(lua_State *L) {
+static int lua_ivm_set(lua_State *L) 
+{
     const char *key, *raw_key;
     const char *value = NULL;
+    size_t str_len;
     lua_ivm_object *object = NULL;
-    lua_ivm_object *old_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);
     
-    apr_pool_userdata_get((void **)&old_object, raw_key, r->server->process->pool);
-    object = apr_pcalloc(r->server->process->pool, sizeof(lua_ivm_object));
+    apr_thread_mutex_lock(lua_ivm_mutex);
+    apr_pool_userdata_get((void **)&object, raw_key, r->server->process->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->size = 1;
+        object->vb_size = 1;
+    }
     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);
-        ap_varbuf_init(r->server->process->pool, &object->vb, object->size);
-        ap_varbuf_strmemcat(&object->vb, value, object->size);
+        value = lua_tolstring(L, 3, &str_len);
+        str_len++; /* add trailing \0 */
+        if ( str_len > object->vb_size) {
+            ap_varbuf_grow(&object->vb, str_len);
+            object->vb_size = str_len;
+        }
+        object->size = str_len-1;
+        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);
-    if (old_object && old_object->type == LUA_TSTRING) {
-        ap_varbuf_free(&old_object->vb);
-    }
+    apr_thread_mutex_unlock(lua_ivm_mutex);
     return 0;
 }
 

Modified: httpd/httpd/trunk/modules/lua/lua_request.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/lua/lua_request.h?rev=1470156&r1=1470155&r2=1470156&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/lua/lua_request.h (original)
+++ httpd/httpd/trunk/modules/lua/lua_request.h Sat Apr 20 12:26:05 2013
@@ -40,6 +40,7 @@ typedef struct
 typedef struct {
     int type;
     size_t size;
+    size_t vb_size;
     lua_Number number;
     struct ap_varbuf vb;
 } lua_ivm_object;

Modified: httpd/httpd/trunk/modules/lua/mod_lua.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/lua/mod_lua.c?rev=1470156&r1=1470155&r2=1470156&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/lua/mod_lua.c (original)
+++ httpd/httpd/trunk/modules/lua/mod_lua.c Sat Apr 20 12:26:05 2013
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <apr_thread_mutex.h>
 
 #include "lua_apr.h"
 #include "lua_config.h"
@@ -63,6 +64,7 @@ typedef struct
     int broken;
 } lua_filter_ctx;
 
+apr_thread_mutex_t* lua_ivm_mutex = NULL;
 
 /**
  * error reporting if lua has an error.
@@ -1970,6 +1972,9 @@ static void lua_register_hooks(apr_pool_
 #endif
     /* providers */
     lua_authz_providers = apr_hash_make(p);
+    
+    /* ivm mutex */
+    apr_thread_mutex_create(&lua_ivm_mutex, APR_THREAD_MUTEX_DEFAULT, p);
 }
 
 AP_DECLARE_MODULE(lua) = {