MINOR: lua: use watcher for proxies iterator

Ensures proxies iteration via lua functions is safe via a new watcher
member. The principle is similar to the one already used for servers
iteration.
This commit is contained in:
Amaury Denoyelle 2026-02-24 17:47:46 +01:00
parent dd1990a97a
commit ebbdfc5915
2 changed files with 33 additions and 4 deletions

View file

@ -222,6 +222,7 @@ struct hlua_proxy_list {
};
struct hlua_proxy_list_iterator_context {
struct watcher px_watch; /* watcher to automatically update next pointer on backend deletion */
struct proxy *next;
char capabilities;
};

View file

@ -2316,13 +2316,30 @@ int hlua_listable_proxies_pairs_iterator(lua_State *L)
lua_pushstring(L, ctx->next->id);
hlua_fcn_new_proxy(L, ctx->next);
for (ctx->next = ctx->next->next;
ctx->next = watcher_next(&ctx->px_watch, ctx->next->next);
for (;
ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities);
ctx->next = ctx->next->next);
ctx->next = watcher_next(&ctx->px_watch, ctx->next->next))
;
return 2;
}
/* ensure proper cleanup for listable_proxies_pairs */
int hlua_listable_proxies_pairs_gc(lua_State *L)
{
struct hlua_proxy_list_iterator_context *ctx;
ctx = lua_touserdata(L, 1);
/* we need to make sure that the watcher leaves in detached state even
* if the iterator was interrupted (ie: "break" from the loop), else
* the server watcher list will become corrupted
*/
watcher_detach(&ctx->px_watch);
return 0;
}
/* init the iterator context, return iterator function
* with context as closure. The only argument is a
* proxy object.
@ -2336,10 +2353,21 @@ int hlua_listable_proxies_pairs(lua_State *L)
ctx = lua_newuserdata(L, sizeof(*ctx));
/* add gc metamethod to the newly created userdata */
lua_newtable(L);
hlua_class_function(L, "__gc", hlua_listable_proxies_pairs_gc);
lua_setmetatable(L, -2);
ctx->capabilities = hlua_px->capabilities;
for (ctx->next = proxies_list;
ctx->next = NULL;
watcher_init(&ctx->px_watch, &ctx->next, offsetof(struct proxy, watcher_list));
for (watcher_attach(&ctx->px_watch, proxies_list);
ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities);
ctx->next = ctx->next->next);
ctx->next = watcher_next(&ctx->px_watch, ctx->next->next))
;
lua_pushcclosure(L, hlua_listable_proxies_pairs_iterator, 1);
return 1;
}