mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-14 13:21:00 +01:00
BUG/MINOR: hlua_fcn: fix broken yield for Patref:add_bulk()
In GH #3241, GH user @kanashimia reported that the Patref:add_bulk() method would raise a Lua exception when called with more than 101 elements at once. As identified by @kanashimia there was an error in the way the add_bulk() method was forced to yield after 101 elements precisely. The yield is there to ensure Lua doesn't eat too much ressources at once and doesn't impact haproxy's core responsiveness, but the check for the yield was misplaced resulting in improper stack content upon resume. Thanks to user @kanashimia who even provided a reproducer which helped a lot to troubleshoot the issue. This fix should be backported up to 3.2 with 884dc62 ("MINOR: hlua_fcn: add Patref:add_bulk()") where the bug was introduced.
This commit is contained in:
parent
b1cfeeef21
commit
04545cb2b7
@ -2808,17 +2808,6 @@ static int _hlua_patref_add_bulk(lua_State *L, int status, lua_KContext ctx)
|
||||
const char *key;
|
||||
const char *value = NULL;
|
||||
|
||||
/* check if we may do something to try to prevent thread contention,
|
||||
* unless we run from body/init state where hlua_yieldk is no-op
|
||||
*/
|
||||
if (count > 100 && hlua_gethlua(L)) {
|
||||
/* let's yield and wait for being called again to continue where we left off */
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
hlua_yieldk(L, 0, 0, _hlua_patref_add_bulk, TICK_ETERNITY, HLUA_CTRLYIELD); // continue
|
||||
return 0; // not reached
|
||||
|
||||
}
|
||||
|
||||
if (ref->ptr->flags & PAT_REF_SMP) {
|
||||
/* key:val table */
|
||||
luaL_checktype(L, -2, LUA_TSTRING);
|
||||
@ -2843,6 +2832,17 @@ static int _hlua_patref_add_bulk(lua_State *L, int status, lua_KContext ctx)
|
||||
/* removes 'value'; keeps 'key' for next iteration */
|
||||
lua_pop(L, 1);
|
||||
count += 1;
|
||||
|
||||
/* check if we may do something to try to prevent thread contention,
|
||||
* unless we run from body/init state where hlua_yieldk is no-op
|
||||
*/
|
||||
if (count > 100 && hlua_gethlua(L)) {
|
||||
/* let's yield and wait for being called again to continue where we left off */
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
hlua_yieldk(L, 0, 0, _hlua_patref_add_bulk, TICK_ETERNITY, HLUA_CTRLYIELD); // continue
|
||||
return 0; // not reached
|
||||
|
||||
}
|
||||
}
|
||||
HA_RWLOCK_WRUNLOCK(PATREF_LOCK, &ref->ptr->lock);
|
||||
lua_pushboolean(L, 1);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user