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.
.. js:function:: core.register_task(func)
.. js:function:: core.register_task(func[, arg1[, arg2[, ...[, arg4]]]])
**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
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:
.. 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)

View File

@ -8686,19 +8686,38 @@ __LJMP static int hlua_register_init(lua_State *L)
*
* 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)
{
struct hlua *hlua = NULL;
struct task *task = NULL;
int ref;
int nb_arg;
int it;
int arg_ref[4]; /* optional arguments */
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));
/* 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
* 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))
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. */
hlua_pushref(hlua->T, ref);
/* function ref not needed anymore since it was pushed to the substack */
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. */
task_wakeup(task, TASK_WOKEN_INIT);
@ -8746,6 +8779,9 @@ static int hlua_register_task(lua_State *L)
alloc_error:
task_destroy(task);
hlua_unref(L, ref);
for (it = 0; it < nb_arg; it++) {
hlua_unref(L, arg_ref[it]);
}
hlua_ctx_destroy(hlua);
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
return 0; /* Never reached */