MINOR: hlua: support for optional arguments to core.register_task()

core.register_task(function) may now take up to 4 additional arguments
that will be passed as-is to the task function.
This could be convenient to spawn sub-tasks from existing functions
supporting core.register_task() without the need to use global
variables to pass some context to the newly created task function.

The new prototype is:

  core.register_task(function[, arg1[, arg2[, ...[, arg4]]]])

Implementation remains backward-compatible with existing scripts.
This commit is contained in:
Aurelien DARRAGON 2023-03-09 16:48:30 +01:00 committed by Christopher Faulet
parent 94ee6632ee
commit b8038996e9
2 changed files with 46 additions and 7 deletions

View File

@ -720,7 +720,7 @@ Core class
It takes no input, and no output is expected. It takes no input, and no output is expected.
.. js:function:: core.register_task(func) .. js:function:: core.register_task(func[, arg1[, arg2[, ...[, arg4]]]])
**context**: body, init, task, action, sample-fetch, converter **context**: body, init, task, action, sample-fetch, converter
@ -728,16 +728,19 @@ Core class
main scheduler starts. For example this type of tasks can be executed to main scheduler starts. For example this type of tasks can be executed to
perform complex health checks. perform complex health checks.
:param function func: is the Lua function called to work as initializer. :param function func: is the Lua function called to work as an async task.
Up to 4 optional arguments (all types supported) may be passed to the function.
(They will be passed as-is to the task function)
The prototype of the Lua function used as argument is: The prototype of the Lua function used as argument is:
.. code-block:: lua .. code-block:: lua
function() function([arg1[, arg2[, ...[, arg4]]]])
.. ..
It takes no input, and no output is expected. It takes up to 4 optional arguments (provided when registering), and no output is expected.
.. js:function:: core.register_cli([path], usage, func) .. js:function:: core.register_cli([path], usage, func)

View File

@ -8686,19 +8686,38 @@ __LJMP static int hlua_register_init(lua_State *L)
* *
* Lua prototype: * Lua prototype:
* *
* <none> core.register_task(<function>) * <none> core.register_task(<function>[, <arg1>[, <arg2>[, ...[, <arg4>]]]])
*
* <arg1..4> are optional arguments that will be provided to <function>
*/ */
static int hlua_register_task(lua_State *L) static int hlua_register_task(lua_State *L)
{ {
struct hlua *hlua = NULL; struct hlua *hlua = NULL;
struct task *task = NULL; struct task *task = NULL;
int ref; int ref;
int nb_arg;
int it;
int arg_ref[4]; /* optional arguments */
int state_id; int state_id;
MAY_LJMP(check_args(L, 1, "register_task")); nb_arg = lua_gettop(L);
if (nb_arg < 1)
WILL_LJMP(luaL_error(L, "register_task: <func> argument is required"));
else if (nb_arg > 5)
WILL_LJMP(luaL_error(L, "register_task: no more that 4 optional arguments may be provided"));
/* first arg: function ref */
ref = MAY_LJMP(hlua_checkfunction(L, 1)); ref = MAY_LJMP(hlua_checkfunction(L, 1));
/* extract optional args (if any) */
it = 0;
while (--nb_arg) {
lua_pushvalue(L, 2 + it);
arg_ref[it] = hlua_ref(L); /* get arg reference */
it += 1;
}
nb_arg = it;
/* Get the reference state. If the reference is NULL, L is the master /* Get the reference state. If the reference is NULL, L is the master
* state, otherwise hlua->T is. * state, otherwise hlua->T is.
*/ */
@ -8731,12 +8750,26 @@ static int hlua_register_task(lua_State *L)
if (!hlua_ctx_init(hlua, state_id, task)) if (!hlua_ctx_init(hlua, state_id, task))
goto alloc_error; goto alloc_error;
/* Ensure there is enough space on the stack for the function
* plus optional arguments
*/
if (!lua_checkstack(hlua->T, (1 + nb_arg)))
goto alloc_error;
/* Restore the function in the stack. */ /* Restore the function in the stack. */
hlua_pushref(hlua->T, ref); hlua_pushref(hlua->T, ref);
/* function ref not needed anymore since it was pushed to the substack */ /* function ref not needed anymore since it was pushed to the substack */
hlua_unref(L, ref); hlua_unref(L, ref);
hlua->nargs = 0; hlua->nargs = nb_arg;
/* push optional arguments to the function */
for (it = 0; it < nb_arg; it++) {
/* push arg to the stack */
hlua_pushref(hlua->T, arg_ref[it]);
/* arg ref not needed anymore since it was pushed to the substack */
hlua_unref(L, arg_ref[it]);
}
/* Schedule task. */ /* Schedule task. */
task_wakeup(task, TASK_WOKEN_INIT); task_wakeup(task, TASK_WOKEN_INIT);
@ -8746,6 +8779,9 @@ static int hlua_register_task(lua_State *L)
alloc_error: alloc_error:
task_destroy(task); task_destroy(task);
hlua_unref(L, ref); hlua_unref(L, ref);
for (it = 0; it < nb_arg; it++) {
hlua_unref(L, arg_ref[it]);
}
hlua_ctx_destroy(hlua); hlua_ctx_destroy(hlua);
WILL_LJMP(luaL_error(L, "Lua out of memory error.")); WILL_LJMP(luaL_error(L, "Lua out of memory error."));
return 0; /* Never reached */ return 0; /* Never reached */