From: Daniel Gruno Date: Sat, 20 Apr 2013 12:26:05 +0000 (+0000) Subject: Use a mutex to control read/write for IVM values, so we can reuse the existing struct... X-Git-Tag: 2.5.0-alpha~5557 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98ebff29d770f92a5f052aae333633687389bed4;p=apache 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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1470156 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c index 8a2ac91636..1351937549 100644 --- a/modules/lua/lua_request.c +++ b/modules/lua/lua_request.c @@ -19,6 +19,7 @@ #include +#include #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; } diff --git a/modules/lua/lua_request.h b/modules/lua/lua_request.h index 903af004f8..9a2488b0f2 100644 --- a/modules/lua/lua_request.h +++ b/modules/lua/lua_request.h @@ -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; diff --git a/modules/lua/mod_lua.c b/modules/lua/mod_lua.c index 6945ce28d0..8c5057249f 100644 --- a/modules/lua/mod_lua.c +++ b/modules/lua/mod_lua.c @@ -19,6 +19,7 @@ #include #include #include +#include #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_t *p) #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) = {