mirror of
https://github.com/apache/httpd.git
synced 2025-08-05 16:55:50 +03:00
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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user