BUG/MINOR: lua: Yield in channel functions only if lua context can yield
When a script is executed, it is not always allowed to yield. Lua sample fetches and converters cannot yield. For lua actions, it depends on the context. When called from tcp content ruleset, an action may yield until the expiration of the inspect-delay timeout. From http rulesets, yield is not possible. Thus, when channel functions (dup, get, append, send...) are called, instead of yielding when it is not allowed and triggering an error, we just give up. In this case, some functions do nothing (dup, append...), some others just interrupt the in-progress job (send, forward...). But, because these functions don't yield anymore when it is not allowed, the script regains the control and can continue its execution. This patch depends on "MINOR: lua: Add a flag on lua context to know the yield capability at run time". Both may be backported in all stable versions. However, because nobody notice this bug till now, it is probably not necessary, excepted if someone ask for it.
This commit is contained in:
parent
1f43a3430e
commit
2e60aa4dee
63
src/hlua.c
63
src/hlua.c
@ -2931,12 +2931,12 @@ static inline int _hlua_channel_dup(struct channel *chn, lua_State *L)
|
||||
luaL_Buffer b;
|
||||
|
||||
ret = ci_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
|
||||
if (unlikely(ret == 0))
|
||||
if (unlikely(ret <= 0)) {
|
||||
if (ret < 0 || HLUA_CANT_YIELD(hlua_gethlua(L))) {
|
||||
lua_pushnil(L);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (unlikely(ret < 0)) {
|
||||
lua_pushnil(L);
|
||||
return -1;
|
||||
}
|
||||
|
||||
luaL_buffinit(L, &b);
|
||||
@ -3037,8 +3037,13 @@ __LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KCont
|
||||
}
|
||||
|
||||
ret = ci_getline_nc(chn, &blk1, &len1, &blk2, &len2);
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
if (HLUA_CANT_YIELD(hlua_gethlua(L))) {
|
||||
_hlua_channel_dup(chn, L);
|
||||
return 1;
|
||||
}
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
lua_pushnil(L);
|
||||
@ -3099,11 +3104,11 @@ __LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KConte
|
||||
max = len - l;
|
||||
|
||||
ret = ci_putblk(chn, str + l, max);
|
||||
if (ret == -2 || ret == -3) {
|
||||
lua_pushinteger(L, -1);
|
||||
return 1;
|
||||
}
|
||||
if (ret == -1) {
|
||||
if (ret < 0) {
|
||||
if (ret == -2 || ret == -3 || HLUA_CANT_YIELD(hlua_gethlua(L))) {
|
||||
lua_pushinteger(L, -1);
|
||||
return 1;
|
||||
}
|
||||
chn->flags |= CF_WAKE_WRITE;
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
@ -3111,16 +3116,16 @@ __LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KConte
|
||||
lua_pop(L, 1);
|
||||
lua_pushinteger(L, l);
|
||||
|
||||
max = channel_recv_limit(chn) - b_data(&chn->buf);
|
||||
if (max == 0 && co_data(chn) == 0) {
|
||||
/* There are no space available, and the output buffer is empty.
|
||||
* in this case, we cannot add more data, so we cannot yield,
|
||||
* we return the amount of copied data.
|
||||
if (l < len) {
|
||||
/* If there are no space available, and the output buffer is
|
||||
* empty, we cannot add more data, so we cannot yield, we return
|
||||
* the amount of copied data.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
if (l < len)
|
||||
max = channel_recv_limit(chn) - b_data(&chn->buf);
|
||||
if ((max == 0 && co_data(chn) == 0) || HLUA_CANT_YIELD(hlua_gethlua(L)))
|
||||
return 1;
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3200,6 +3205,8 @@ __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext
|
||||
* the request buffer if its not required.
|
||||
*/
|
||||
if (chn->buf.size == 0) {
|
||||
if (HLUA_CANT_YIELD(hlua_gethlua(L)))
|
||||
return 1;
|
||||
si_rx_buff_blk(chn_prod(chn));
|
||||
MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
|
||||
}
|
||||
@ -3240,15 +3247,15 @@ __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext
|
||||
lua_pop(L, 1);
|
||||
lua_pushinteger(L, l);
|
||||
|
||||
/* If there is no space available, and the output buffer is empty.
|
||||
* in this case, we cannot add more data, so we cannot yield,
|
||||
* we return the amount of copied data.
|
||||
*/
|
||||
max = b_room(&chn->buf);
|
||||
if (max == 0 && co_data(chn) == 0)
|
||||
return 1;
|
||||
|
||||
if (l < len) {
|
||||
/* If there is no space available, and the output buffer is empty.
|
||||
* in this case, we cannot add more data, so we cannot yield,
|
||||
* we return the amount of copied data.
|
||||
*/
|
||||
max = b_room(&chn->buf);
|
||||
if ((max == 0 && co_data(chn) == 0) || HLUA_CANT_YIELD(hlua_gethlua(L)))
|
||||
return 1;
|
||||
|
||||
/* If we are waiting for space in the response buffer, we
|
||||
* must set the flag WAKERESWR. This flag required the task
|
||||
* wake up if any activity is detected on the response buffer.
|
||||
@ -3319,7 +3326,7 @@ __LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KCont
|
||||
/* The the input channel or the output channel are closed, we
|
||||
* must return the amount of data forwarded.
|
||||
*/
|
||||
if (channel_input_closed(chn) || channel_output_closed(chn))
|
||||
if (channel_input_closed(chn) || channel_output_closed(chn) || HLUA_CANT_YIELD(hlua_gethlua(L)))
|
||||
return 1;
|
||||
|
||||
/* If we are waiting for space data in the response buffer, we
|
||||
|
Loading…
x
Reference in New Issue
Block a user