mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-08 08:07:10 +02:00
MEDIUM: lua: remove Lua struct from session, and allocate it with memory pools
This patch use memory pools for allocating the Lua struct. This save 128B of memory in the session if the Lua is unused.
This commit is contained in:
parent
1be34152da
commit
2c8b54e7be
@ -165,7 +165,7 @@ struct stream {
|
|||||||
/* These two pointers are used to resume the execution of the rule lists. */
|
/* These two pointers are used to resume the execution of the rule lists. */
|
||||||
struct list *current_rule_list; /* this is used to store the current executed rule list. */
|
struct list *current_rule_list; /* this is used to store the current executed rule list. */
|
||||||
void *current_rule; /* this is used to store the current rule to be resumed. */
|
void *current_rule; /* this is used to store the current rule to be resumed. */
|
||||||
struct hlua hlua; /* lua runtime context */
|
struct hlua *hlua; /* lua runtime context */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TYPES_STREAM_H */
|
#endif /* _TYPES_STREAM_H */
|
||||||
|
242
src/hlua.c
242
src/hlua.c
@ -874,9 +874,12 @@ int hlua_ctx_init(struct hlua *lua, struct task *task)
|
|||||||
*/
|
*/
|
||||||
void hlua_ctx_destroy(struct hlua *lua)
|
void hlua_ctx_destroy(struct hlua *lua)
|
||||||
{
|
{
|
||||||
if (!lua->T)
|
if (!lua)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!lua->T)
|
||||||
|
goto end;
|
||||||
|
|
||||||
/* Purge all the pending signals. */
|
/* Purge all the pending signals. */
|
||||||
hlua_com_purge(&lua->com);
|
hlua_com_purge(&lua->com);
|
||||||
|
|
||||||
@ -899,6 +902,9 @@ void hlua_ctx_destroy(struct hlua *lua)
|
|||||||
}
|
}
|
||||||
|
|
||||||
lua->T = NULL;
|
lua->T = NULL;
|
||||||
|
|
||||||
|
end:
|
||||||
|
pool_free2(pool2_hlua, lua);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is used to restore the Lua context when a coroutine
|
/* This function is used to restore the Lua context when a coroutine
|
||||||
@ -2332,12 +2338,7 @@ __LJMP static int hlua_socket_new(lua_State *L)
|
|||||||
|
|
||||||
/* Configure an empty Lua for the stream. */
|
/* Configure an empty Lua for the stream. */
|
||||||
socket->s = strm;
|
socket->s = strm;
|
||||||
strm->hlua.T = NULL;
|
strm->hlua = NULL;
|
||||||
strm->hlua.Tref = LUA_REFNIL;
|
|
||||||
strm->hlua.Mref = LUA_REFNIL;
|
|
||||||
strm->hlua.nargs = 0;
|
|
||||||
strm->hlua.flags = 0;
|
|
||||||
LIST_INIT(&strm->hlua.com);
|
|
||||||
|
|
||||||
/* Configure "right" stream interface. this "si" is used to connect
|
/* Configure "right" stream interface. this "si" is used to connect
|
||||||
* and retrieve data from the server. The connection is initialized
|
* and retrieve data from the server. The connection is initialized
|
||||||
@ -3303,7 +3304,9 @@ __LJMP static int hlua_applet_tcp_set_priv(lua_State *L)
|
|||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
|
|
||||||
/* Note that this hlua struct is from the session and not from the applet. */
|
/* Note that this hlua struct is from the session and not from the applet. */
|
||||||
hlua = &s->hlua;
|
if (!s->hlua)
|
||||||
|
return 0;
|
||||||
|
hlua = s->hlua;
|
||||||
|
|
||||||
MAY_LJMP(check_args(L, 2, "set_priv"));
|
MAY_LJMP(check_args(L, 2, "set_priv"));
|
||||||
|
|
||||||
@ -3325,7 +3328,11 @@ __LJMP static int hlua_applet_tcp_get_priv(lua_State *L)
|
|||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
|
|
||||||
/* Note that this hlua struct is from the session and not from the applet. */
|
/* Note that this hlua struct is from the session and not from the applet. */
|
||||||
hlua = &s->hlua;
|
if (!s->hlua) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
hlua = s->hlua;
|
||||||
|
|
||||||
/* Push configuration index in the stack. */
|
/* Push configuration index in the stack. */
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
|
||||||
@ -3757,7 +3764,9 @@ __LJMP static int hlua_applet_http_set_priv(lua_State *L)
|
|||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
|
|
||||||
/* Note that this hlua struct is from the session and not from the applet. */
|
/* Note that this hlua struct is from the session and not from the applet. */
|
||||||
hlua = &s->hlua;
|
if (!s->hlua)
|
||||||
|
return 0;
|
||||||
|
hlua = s->hlua;
|
||||||
|
|
||||||
MAY_LJMP(check_args(L, 2, "set_priv"));
|
MAY_LJMP(check_args(L, 2, "set_priv"));
|
||||||
|
|
||||||
@ -3779,7 +3788,11 @@ __LJMP static int hlua_applet_http_get_priv(lua_State *L)
|
|||||||
struct hlua *hlua;
|
struct hlua *hlua;
|
||||||
|
|
||||||
/* Note that this hlua struct is from the session and not from the applet. */
|
/* Note that this hlua struct is from the session and not from the applet. */
|
||||||
hlua = &s->hlua;
|
if (!s->hlua) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
hlua = s->hlua;
|
||||||
|
|
||||||
/* Push configuration index in the stack. */
|
/* Push configuration index in the stack. */
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
|
||||||
@ -5300,7 +5313,6 @@ static struct task *hlua_process_task(struct task *task)
|
|||||||
/* finished or yield */
|
/* finished or yield */
|
||||||
case HLUA_E_OK:
|
case HLUA_E_OK:
|
||||||
hlua_ctx_destroy(hlua);
|
hlua_ctx_destroy(hlua);
|
||||||
free(hlua);
|
|
||||||
task_delete(task);
|
task_delete(task);
|
||||||
task_free(task);
|
task_free(task);
|
||||||
break;
|
break;
|
||||||
@ -5314,7 +5326,6 @@ static struct task *hlua_process_task(struct task *task)
|
|||||||
case HLUA_E_ERRMSG:
|
case HLUA_E_ERRMSG:
|
||||||
SEND_ERR(NULL, "Lua task: %s.\n", lua_tostring(hlua->T, -1));
|
SEND_ERR(NULL, "Lua task: %s.\n", lua_tostring(hlua->T, -1));
|
||||||
hlua_ctx_destroy(hlua);
|
hlua_ctx_destroy(hlua);
|
||||||
free(hlua);
|
|
||||||
task_delete(task);
|
task_delete(task);
|
||||||
task_free(task);
|
task_free(task);
|
||||||
break;
|
break;
|
||||||
@ -5323,7 +5334,6 @@ static struct task *hlua_process_task(struct task *task)
|
|||||||
default:
|
default:
|
||||||
SEND_ERR(NULL, "Lua task: unknown error.\n");
|
SEND_ERR(NULL, "Lua task: unknown error.\n");
|
||||||
hlua_ctx_destroy(hlua);
|
hlua_ctx_destroy(hlua);
|
||||||
free(hlua);
|
|
||||||
task_delete(task);
|
task_delete(task);
|
||||||
task_free(task);
|
task_free(task);
|
||||||
break;
|
break;
|
||||||
@ -5374,7 +5384,7 @@ static int hlua_register_task(lua_State *L)
|
|||||||
|
|
||||||
ref = MAY_LJMP(hlua_checkfunction(L, 1));
|
ref = MAY_LJMP(hlua_checkfunction(L, 1));
|
||||||
|
|
||||||
hlua = calloc(1, sizeof(*hlua));
|
hlua = pool_alloc2(pool2_hlua);
|
||||||
if (!hlua)
|
if (!hlua)
|
||||||
WILL_LJMP(luaL_error(L, "lua out of memory error."));
|
WILL_LJMP(luaL_error(L, "lua out of memory error."));
|
||||||
|
|
||||||
@ -5413,18 +5423,25 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp,
|
|||||||
* permits to save performances because a systematic
|
* permits to save performances because a systematic
|
||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!stream->hlua.T && !hlua_ctx_init(&stream->hlua, stream->task)) {
|
if (!stream->hlua) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
stream->hlua = pool_alloc2(pool2_hlua);
|
||||||
return 0;
|
if (!stream->hlua) {
|
||||||
|
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!hlua_ctx_init(stream->hlua, stream->task)) {
|
||||||
|
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If it is the first run, initialize the data for the call. */
|
/* If it is the first run, initialize the data for the call. */
|
||||||
if (!HLUA_IS_RUNNING(&stream->hlua)) {
|
if (!HLUA_IS_RUNNING(stream->hlua)) {
|
||||||
|
|
||||||
/* The following Lua calls can fail. */
|
/* The following Lua calls can fail. */
|
||||||
if (!SET_SAFE_LJMP(stream->hlua.T)) {
|
if (!SET_SAFE_LJMP(stream->hlua->T)) {
|
||||||
if (lua_type(stream->hlua.T, -1) == LUA_TSTRING)
|
if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
|
||||||
error = lua_tostring(stream->hlua.T, -1);
|
error = lua_tostring(stream->hlua->T, -1);
|
||||||
else
|
else
|
||||||
error = "critical error";
|
error = "critical error";
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': %s.\n", fcn->name, error);
|
SEND_ERR(stream->be, "Lua converter '%s': %s.\n", fcn->name, error);
|
||||||
@ -5432,51 +5449,51 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check stack available size. */
|
/* Check stack available size. */
|
||||||
if (!lua_checkstack(stream->hlua.T, 1)) {
|
if (!lua_checkstack(stream->hlua->T, 1)) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the function in the stack. */
|
/* Restore the function in the stack. */
|
||||||
lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
|
lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
|
||||||
|
|
||||||
/* convert input sample and pust-it in the stack. */
|
/* convert input sample and pust-it in the stack. */
|
||||||
if (!lua_checkstack(stream->hlua.T, 1)) {
|
if (!lua_checkstack(stream->hlua->T, 1)) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hlua_smp2lua(stream->hlua.T, smp);
|
hlua_smp2lua(stream->hlua->T, smp);
|
||||||
stream->hlua.nargs = 1;
|
stream->hlua->nargs = 1;
|
||||||
|
|
||||||
/* push keywords in the stack. */
|
/* push keywords in the stack. */
|
||||||
if (arg_p) {
|
if (arg_p) {
|
||||||
for (; arg_p->type != ARGT_STOP; arg_p++) {
|
for (; arg_p->type != ARGT_STOP; arg_p++) {
|
||||||
if (!lua_checkstack(stream->hlua.T, 1)) {
|
if (!lua_checkstack(stream->hlua->T, 1)) {
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hlua_arg2lua(stream->hlua.T, arg_p);
|
hlua_arg2lua(stream->hlua->T, arg_p);
|
||||||
stream->hlua.nargs++;
|
stream->hlua->nargs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We must initialize the execution timeouts. */
|
/* We must initialize the execution timeouts. */
|
||||||
stream->hlua.max_time = hlua_timeout_session;
|
stream->hlua->max_time = hlua_timeout_session;
|
||||||
|
|
||||||
/* At this point the execution is safe. */
|
/* At this point the execution is safe. */
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the function. */
|
/* Execute the function. */
|
||||||
switch (hlua_ctx_resume(&stream->hlua, 0)) {
|
switch (hlua_ctx_resume(stream->hlua, 0)) {
|
||||||
/* finished. */
|
/* finished. */
|
||||||
case HLUA_E_OK:
|
case HLUA_E_OK:
|
||||||
/* Convert the returned value in sample. */
|
/* Convert the returned value in sample. */
|
||||||
hlua_lua2smp(stream->hlua.T, -1, smp);
|
hlua_lua2smp(stream->hlua->T, -1, smp);
|
||||||
lua_pop(stream->hlua.T, 1);
|
lua_pop(stream->hlua->T, 1);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* yield. */
|
/* yield. */
|
||||||
@ -5488,8 +5505,8 @@ static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp,
|
|||||||
case HLUA_E_ERRMSG:
|
case HLUA_E_ERRMSG:
|
||||||
/* Display log. */
|
/* Display log. */
|
||||||
SEND_ERR(stream->be, "Lua converter '%s': %s.\n",
|
SEND_ERR(stream->be, "Lua converter '%s': %s.\n",
|
||||||
fcn->name, lua_tostring(stream->hlua.T, -1));
|
fcn->name, lua_tostring(stream->hlua->T, -1));
|
||||||
lua_pop(stream->hlua.T, 1);
|
lua_pop(stream->hlua->T, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HLUA_E_ERR:
|
case HLUA_E_ERR:
|
||||||
@ -5522,20 +5539,27 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
|
|||||||
* permits to save performances because a systematic
|
* permits to save performances because a systematic
|
||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!stream->hlua.T && !hlua_ctx_init(&stream->hlua, stream->task)) {
|
if (!stream->hlua) {
|
||||||
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
stream->hlua = pool_alloc2(pool2_hlua);
|
||||||
return 0;
|
if (!stream->hlua) {
|
||||||
|
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!hlua_ctx_init(stream->hlua, stream->task)) {
|
||||||
|
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
consistency_set(stream, smp->opt, &stream->hlua.cons);
|
consistency_set(stream, smp->opt, &stream->hlua->cons);
|
||||||
|
|
||||||
/* If it is the first run, initialize the data for the call. */
|
/* If it is the first run, initialize the data for the call. */
|
||||||
if (!HLUA_IS_RUNNING(&stream->hlua)) {
|
if (!HLUA_IS_RUNNING(stream->hlua)) {
|
||||||
|
|
||||||
/* The following Lua calls can fail. */
|
/* The following Lua calls can fail. */
|
||||||
if (!SET_SAFE_LJMP(stream->hlua.T)) {
|
if (!SET_SAFE_LJMP(stream->hlua->T)) {
|
||||||
if (lua_type(stream->hlua.T, -1) == LUA_TSTRING)
|
if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
|
||||||
error = lua_tostring(stream->hlua.T, -1);
|
error = lua_tostring(stream->hlua->T, -1);
|
||||||
else
|
else
|
||||||
error = "critical error";
|
error = "critical error";
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", fcn->name, error);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", fcn->name, error);
|
||||||
@ -5543,54 +5567,54 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check stack available size. */
|
/* Check stack available size. */
|
||||||
if (!lua_checkstack(stream->hlua.T, 2)) {
|
if (!lua_checkstack(stream->hlua->T, 2)) {
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the function in the stack. */
|
/* Restore the function in the stack. */
|
||||||
lua_rawgeti(stream->hlua.T, LUA_REGISTRYINDEX, fcn->function_ref);
|
lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
|
||||||
|
|
||||||
/* push arguments in the stack. */
|
/* push arguments in the stack. */
|
||||||
if (!hlua_txn_new(stream->hlua.T, stream, smp->px, smp->opt & SMP_OPT_DIR,
|
if (!hlua_txn_new(stream->hlua->T, stream, smp->px, smp->opt & SMP_OPT_DIR,
|
||||||
HLUA_TXN_NOTERM)) {
|
HLUA_TXN_NOTERM)) {
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream->hlua.nargs = 1;
|
stream->hlua->nargs = 1;
|
||||||
|
|
||||||
/* push keywords in the stack. */
|
/* push keywords in the stack. */
|
||||||
for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
|
for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
|
||||||
/* Check stack available size. */
|
/* Check stack available size. */
|
||||||
if (!lua_checkstack(stream->hlua.T, 1)) {
|
if (!lua_checkstack(stream->hlua->T, 1)) {
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hlua_arg2lua(stream->hlua.T, arg_p);
|
hlua_arg2lua(stream->hlua->T, arg_p);
|
||||||
stream->hlua.nargs++;
|
stream->hlua->nargs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We must initialize the execution timeouts. */
|
/* We must initialize the execution timeouts. */
|
||||||
stream->hlua.max_time = hlua_timeout_session;
|
stream->hlua->max_time = hlua_timeout_session;
|
||||||
|
|
||||||
/* At this point the execution is safe. */
|
/* At this point the execution is safe. */
|
||||||
RESET_SAFE_LJMP(stream->hlua.T);
|
RESET_SAFE_LJMP(stream->hlua->T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the function. */
|
/* Execute the function. */
|
||||||
switch (hlua_ctx_resume(&stream->hlua, 0)) {
|
switch (hlua_ctx_resume(stream->hlua, 0)) {
|
||||||
/* finished. */
|
/* finished. */
|
||||||
case HLUA_E_OK:
|
case HLUA_E_OK:
|
||||||
if (!consistency_check(stream, smp->opt, &stream->hlua.cons)) {
|
if (!consistency_check(stream, smp->opt, &stream->hlua->cons)) {
|
||||||
stream_int_retnclose(&stream->si[0], &msg);
|
stream_int_retnclose(&stream->si[0], &msg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Convert the returned value in sample. */
|
/* Convert the returned value in sample. */
|
||||||
hlua_lua2smp(stream->hlua.T, -1, smp);
|
hlua_lua2smp(stream->hlua->T, -1, smp);
|
||||||
lua_pop(stream->hlua.T, 1);
|
lua_pop(stream->hlua->T, 1);
|
||||||
|
|
||||||
/* Set the end of execution flag. */
|
/* Set the end of execution flag. */
|
||||||
smp->flags &= ~SMP_F_MAY_CHANGE;
|
smp->flags &= ~SMP_F_MAY_CHANGE;
|
||||||
@ -5598,23 +5622,23 @@ static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp
|
|||||||
|
|
||||||
/* yield. */
|
/* yield. */
|
||||||
case HLUA_E_AGAIN:
|
case HLUA_E_AGAIN:
|
||||||
if (!consistency_check(stream, smp->opt, &stream->hlua.cons))
|
if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
|
||||||
stream_int_retnclose(&stream->si[0], &msg);
|
stream_int_retnclose(&stream->si[0], &msg);
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* finished with error. */
|
/* finished with error. */
|
||||||
case HLUA_E_ERRMSG:
|
case HLUA_E_ERRMSG:
|
||||||
if (!consistency_check(stream, smp->opt, &stream->hlua.cons))
|
if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
|
||||||
stream_int_retnclose(&stream->si[0], &msg);
|
stream_int_retnclose(&stream->si[0], &msg);
|
||||||
/* Display log. */
|
/* Display log. */
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n",
|
SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n",
|
||||||
fcn->name, lua_tostring(stream->hlua.T, -1));
|
fcn->name, lua_tostring(stream->hlua->T, -1));
|
||||||
lua_pop(stream->hlua.T, 1);
|
lua_pop(stream->hlua->T, 1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HLUA_E_ERR:
|
case HLUA_E_ERR:
|
||||||
if (!consistency_check(stream, smp->opt, &stream->hlua.cons))
|
if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
|
||||||
stream_int_retnclose(&stream->si[0], &msg);
|
stream_int_retnclose(&stream->si[0], &msg);
|
||||||
/* Display log. */
|
/* Display log. */
|
||||||
SEND_ERR(smp->px, "Lua sample-fetch '%s' returns an unknown error.\n", fcn->name);
|
SEND_ERR(smp->px, "Lua sample-fetch '%s' returns an unknown error.\n", fcn->name);
|
||||||
@ -5764,26 +5788,34 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
|
|||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
consistency_set(s, dir, &s->hlua.cons);
|
|
||||||
|
|
||||||
/* In the execution wrappers linked with a stream, the
|
/* In the execution wrappers linked with a stream, the
|
||||||
* Lua context can be not initialized. This behavior
|
* Lua context can be not initialized. This behavior
|
||||||
* permits to save performances because a systematic
|
* permits to save performances because a systematic
|
||||||
* Lua initialization cause 5% performances loss.
|
* Lua initialization cause 5% performances loss.
|
||||||
*/
|
*/
|
||||||
if (!s->hlua.T && !hlua_ctx_init(&s->hlua, s->task)) {
|
if (!s->hlua) {
|
||||||
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
s->hlua = pool_alloc2(pool2_hlua);
|
||||||
rule->arg.hlua_rule->fcn.name);
|
if (!s->hlua) {
|
||||||
return ACT_RET_CONT;
|
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
||||||
|
rule->arg.hlua_rule->fcn.name);
|
||||||
|
return ACT_RET_CONT;
|
||||||
|
}
|
||||||
|
if (!hlua_ctx_init(s->hlua, s->task)) {
|
||||||
|
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
|
||||||
|
rule->arg.hlua_rule->fcn.name);
|
||||||
|
return ACT_RET_CONT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
consistency_set(s, dir, &s->hlua->cons);
|
||||||
|
|
||||||
/* If it is the first run, initialize the data for the call. */
|
/* If it is the first run, initialize the data for the call. */
|
||||||
if (!HLUA_IS_RUNNING(&s->hlua)) {
|
if (!HLUA_IS_RUNNING(s->hlua)) {
|
||||||
|
|
||||||
/* The following Lua calls can fail. */
|
/* The following Lua calls can fail. */
|
||||||
if (!SET_SAFE_LJMP(s->hlua.T)) {
|
if (!SET_SAFE_LJMP(s->hlua->T)) {
|
||||||
if (lua_type(s->hlua.T, -1) == LUA_TSTRING)
|
if (lua_type(s->hlua->T, -1) == LUA_TSTRING)
|
||||||
error = lua_tostring(s->hlua.T, -1);
|
error = lua_tostring(s->hlua->T, -1);
|
||||||
else
|
else
|
||||||
error = "critical error";
|
error = "critical error";
|
||||||
SEND_ERR(px, "Lua function '%s': %s.\n",
|
SEND_ERR(px, "Lua function '%s': %s.\n",
|
||||||
@ -5792,75 +5824,75 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check stack available size. */
|
/* Check stack available size. */
|
||||||
if (!lua_checkstack(s->hlua.T, 1)) {
|
if (!lua_checkstack(s->hlua->T, 1)) {
|
||||||
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
||||||
rule->arg.hlua_rule->fcn.name);
|
rule->arg.hlua_rule->fcn.name);
|
||||||
RESET_SAFE_LJMP(s->hlua.T);
|
RESET_SAFE_LJMP(s->hlua->T);
|
||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the function in the stack. */
|
/* Restore the function in the stack. */
|
||||||
lua_rawgeti(s->hlua.T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
|
lua_rawgeti(s->hlua->T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
|
||||||
|
|
||||||
/* Create and and push object stream in the stack. */
|
/* Create and and push object stream in the stack. */
|
||||||
if (!hlua_txn_new(s->hlua.T, s, px, dir, 0)) {
|
if (!hlua_txn_new(s->hlua->T, s, px, dir, 0)) {
|
||||||
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
||||||
rule->arg.hlua_rule->fcn.name);
|
rule->arg.hlua_rule->fcn.name);
|
||||||
RESET_SAFE_LJMP(s->hlua.T);
|
RESET_SAFE_LJMP(s->hlua->T);
|
||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
}
|
}
|
||||||
s->hlua.nargs = 1;
|
s->hlua->nargs = 1;
|
||||||
|
|
||||||
/* push keywords in the stack. */
|
/* push keywords in the stack. */
|
||||||
for (arg = rule->arg.hlua_rule->args; arg && *arg; arg++) {
|
for (arg = rule->arg.hlua_rule->args; arg && *arg; arg++) {
|
||||||
if (!lua_checkstack(s->hlua.T, 1)) {
|
if (!lua_checkstack(s->hlua->T, 1)) {
|
||||||
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
SEND_ERR(px, "Lua function '%s': full stack.\n",
|
||||||
rule->arg.hlua_rule->fcn.name);
|
rule->arg.hlua_rule->fcn.name);
|
||||||
RESET_SAFE_LJMP(s->hlua.T);
|
RESET_SAFE_LJMP(s->hlua->T);
|
||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
}
|
}
|
||||||
lua_pushstring(s->hlua.T, *arg);
|
lua_pushstring(s->hlua->T, *arg);
|
||||||
s->hlua.nargs++;
|
s->hlua->nargs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now the execution is safe. */
|
/* Now the execution is safe. */
|
||||||
RESET_SAFE_LJMP(s->hlua.T);
|
RESET_SAFE_LJMP(s->hlua->T);
|
||||||
|
|
||||||
/* We must initialize the execution timeouts. */
|
/* We must initialize the execution timeouts. */
|
||||||
s->hlua.max_time = hlua_timeout_session;
|
s->hlua->max_time = hlua_timeout_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the function. */
|
/* Execute the function. */
|
||||||
switch (hlua_ctx_resume(&s->hlua, !(flags & ACT_FLAG_FINAL))) {
|
switch (hlua_ctx_resume(s->hlua, !(flags & ACT_FLAG_FINAL))) {
|
||||||
/* finished. */
|
/* finished. */
|
||||||
case HLUA_E_OK:
|
case HLUA_E_OK:
|
||||||
if (!consistency_check(s, dir, &s->hlua.cons)) {
|
if (!consistency_check(s, dir, &s->hlua->cons)) {
|
||||||
stream_int_retnclose(&s->si[0], &msg);
|
stream_int_retnclose(&s->si[0], &msg);
|
||||||
return ACT_RET_ERR;
|
return ACT_RET_ERR;
|
||||||
}
|
}
|
||||||
if (s->hlua.flags & HLUA_STOP)
|
if (s->hlua->flags & HLUA_STOP)
|
||||||
return ACT_RET_STOP;
|
return ACT_RET_STOP;
|
||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
|
|
||||||
/* yield. */
|
/* yield. */
|
||||||
case HLUA_E_AGAIN:
|
case HLUA_E_AGAIN:
|
||||||
/* Set timeout in the required channel. */
|
/* Set timeout in the required channel. */
|
||||||
if (s->hlua.wake_time != TICK_ETERNITY) {
|
if (s->hlua->wake_time != TICK_ETERNITY) {
|
||||||
if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
|
if (analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE))
|
||||||
s->req.analyse_exp = s->hlua.wake_time;
|
s->req.analyse_exp = s->hlua->wake_time;
|
||||||
else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
|
else if (analyzer & (AN_RES_INSPECT|AN_RES_HTTP_PROCESS_BE))
|
||||||
s->res.analyse_exp = s->hlua.wake_time;
|
s->res.analyse_exp = s->hlua->wake_time;
|
||||||
}
|
}
|
||||||
/* Some actions can be wake up when a "write" event
|
/* Some actions can be wake up when a "write" event
|
||||||
* is detected on a response channel. This is useful
|
* is detected on a response channel. This is useful
|
||||||
* only for actions targetted on the requests.
|
* only for actions targetted on the requests.
|
||||||
*/
|
*/
|
||||||
if (HLUA_IS_WAKERESWR(&s->hlua)) {
|
if (HLUA_IS_WAKERESWR(s->hlua)) {
|
||||||
s->res.flags |= CF_WAKE_WRITE;
|
s->res.flags |= CF_WAKE_WRITE;
|
||||||
if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
|
if ((analyzer & (AN_REQ_INSPECT_FE|AN_REQ_HTTP_PROCESS_FE)))
|
||||||
s->res.analysers |= analyzer;
|
s->res.analysers |= analyzer;
|
||||||
}
|
}
|
||||||
if (HLUA_IS_WAKEREQWR(&s->hlua))
|
if (HLUA_IS_WAKEREQWR(s->hlua))
|
||||||
s->req.flags |= CF_WAKE_WRITE;
|
s->req.flags |= CF_WAKE_WRITE;
|
||||||
/* We can quit the fcuntion without consistency check
|
/* We can quit the fcuntion without consistency check
|
||||||
* because HAProxy is not able to manipulate data, it
|
* because HAProxy is not able to manipulate data, it
|
||||||
@ -5869,18 +5901,18 @@ static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
|
|||||||
|
|
||||||
/* finished with error. */
|
/* finished with error. */
|
||||||
case HLUA_E_ERRMSG:
|
case HLUA_E_ERRMSG:
|
||||||
if (!consistency_check(s, dir, &s->hlua.cons)) {
|
if (!consistency_check(s, dir, &s->hlua->cons)) {
|
||||||
stream_int_retnclose(&s->si[0], &msg);
|
stream_int_retnclose(&s->si[0], &msg);
|
||||||
return ACT_RET_ERR;
|
return ACT_RET_ERR;
|
||||||
}
|
}
|
||||||
/* Display log. */
|
/* Display log. */
|
||||||
SEND_ERR(px, "Lua function '%s': %s.\n",
|
SEND_ERR(px, "Lua function '%s': %s.\n",
|
||||||
rule->arg.hlua_rule->fcn.name, lua_tostring(s->hlua.T, -1));
|
rule->arg.hlua_rule->fcn.name, lua_tostring(s->hlua->T, -1));
|
||||||
lua_pop(s->hlua.T, 1);
|
lua_pop(s->hlua->T, 1);
|
||||||
return ACT_RET_CONT;
|
return ACT_RET_CONT;
|
||||||
|
|
||||||
case HLUA_E_ERR:
|
case HLUA_E_ERR:
|
||||||
if (!consistency_check(s, dir, &s->hlua.cons)) {
|
if (!consistency_check(s, dir, &s->hlua->cons)) {
|
||||||
stream_int_retnclose(&s->si[0], &msg);
|
stream_int_retnclose(&s->si[0], &msg);
|
||||||
return ACT_RET_ERR;
|
return ACT_RET_ERR;
|
||||||
}
|
}
|
||||||
@ -6075,7 +6107,6 @@ static void hlua_applet_tcp_release(struct appctx *ctx)
|
|||||||
task_free(ctx->ctx.hlua_apptcp.task);
|
task_free(ctx->ctx.hlua_apptcp.task);
|
||||||
ctx->ctx.hlua_apptcp.task = NULL;
|
ctx->ctx.hlua_apptcp.task = NULL;
|
||||||
hlua_ctx_destroy(ctx->ctx.hlua_apptcp.hlua);
|
hlua_ctx_destroy(ctx->ctx.hlua_apptcp.hlua);
|
||||||
pool_free2(pool2_hlua, ctx->ctx.hlua_apptcp.hlua);
|
|
||||||
ctx->ctx.hlua_apptcp.hlua = NULL;
|
ctx->ctx.hlua_apptcp.hlua = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6362,7 +6393,6 @@ static void hlua_applet_http_release(struct appctx *ctx)
|
|||||||
task_free(ctx->ctx.hlua_apphttp.task);
|
task_free(ctx->ctx.hlua_apphttp.task);
|
||||||
ctx->ctx.hlua_apphttp.task = NULL;
|
ctx->ctx.hlua_apphttp.task = NULL;
|
||||||
hlua_ctx_destroy(ctx->ctx.hlua_apphttp.hlua);
|
hlua_ctx_destroy(ctx->ctx.hlua_apphttp.hlua);
|
||||||
pool_free2(pool2_hlua, ctx->ctx.hlua_apphttp.hlua);
|
|
||||||
ctx->ctx.hlua_apphttp.hlua = NULL;
|
ctx->ctx.hlua_apphttp.hlua = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6741,7 +6771,6 @@ static int hlua_cli_parse_fct(char **args, struct appctx *appctx, void *private)
|
|||||||
error:
|
error:
|
||||||
RESET_SAFE_LJMP(hlua->T);
|
RESET_SAFE_LJMP(hlua->T);
|
||||||
hlua_ctx_destroy(hlua);
|
hlua_ctx_destroy(hlua);
|
||||||
pool_free2(pool2_hlua, hlua);
|
|
||||||
appctx->ctx.hlua_cli.hlua = NULL;
|
appctx->ctx.hlua_cli.hlua = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -6801,7 +6830,6 @@ static int hlua_cli_io_handler_fct(struct appctx *appctx)
|
|||||||
static void hlua_cli_io_release_fct(struct appctx *appctx)
|
static void hlua_cli_io_release_fct(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
hlua_ctx_destroy(appctx->ctx.hlua_cli.hlua);
|
hlua_ctx_destroy(appctx->ctx.hlua_cli.hlua);
|
||||||
pool_free2(pool2_hlua, appctx->ctx.hlua_cli.hlua);
|
|
||||||
appctx->ctx.hlua_cli.hlua = NULL;
|
appctx->ctx.hlua_cli.hlua = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,8 +221,7 @@ struct stream *stream_new(struct session *sess, struct task *t, enum obj_type *o
|
|||||||
s->res.analyse_exp = TICK_ETERNITY;
|
s->res.analyse_exp = TICK_ETERNITY;
|
||||||
|
|
||||||
s->txn = NULL;
|
s->txn = NULL;
|
||||||
|
s->hlua = NULL;
|
||||||
HLUA_INIT(&s->hlua);
|
|
||||||
|
|
||||||
if (flt_stream_init(s) < 0 || flt_stream_start(s) < 0)
|
if (flt_stream_init(s) < 0 || flt_stream_start(s) < 0)
|
||||||
goto out_fail_accept;
|
goto out_fail_accept;
|
||||||
@ -299,7 +298,8 @@ static void stream_free(struct stream *s)
|
|||||||
offer_buffers(NULL, tasks_run_queue + applets_active_queue);
|
offer_buffers(NULL, tasks_run_queue + applets_active_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
hlua_ctx_destroy(&s->hlua);
|
hlua_ctx_destroy(s->hlua);
|
||||||
|
s->hlua = NULL;
|
||||||
if (s->txn)
|
if (s->txn)
|
||||||
http_end_txn(s);
|
http_end_txn(s);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user