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.
diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst
index 146c050..917b684 100644
--- a/doc/lua-api/index.rst
+++ b/doc/lua-api/index.rst
@@ -720,7 +720,7 @@
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 @@
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)
diff --git a/src/hlua.c b/src/hlua.c
index 19f848a..7e0a1ca 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -8686,19 +8686,38 @@
*
* 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 @@
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 @@
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 */