diff --git a/doc/lua-api/index.rst b/doc/lua-api/index.rst index 8671f3e44..07e9029e3 100644 --- a/doc/lua-api/index.rst +++ b/doc/lua-api/index.rst @@ -402,6 +402,19 @@ Core class :returns: A socket class object. +.. js:function:: core.done(data) + + **context**: body, init, task, action, sample-fetch, converter + + :param any data: Return some data for the caller. It is useful with + sample-fetches and sample-converters. + + Immediately stops the current Lua execution and returns to the caller which + may be a sample fetch, a converter or an action and returns the specified + value (ignored for actions). It is used when the LUA process finishes its + work and wants to give back the control to HAProxy without executing the + remaining code. It can be seen as a multi-level "return". + .. js:function:: core.yield() **context**: task, action, sample-fetch, converter diff --git a/include/types/hlua.h b/include/types/hlua.h index f481bdfa9..453980b54 100644 --- a/include/types/hlua.h +++ b/include/types/hlua.h @@ -24,6 +24,7 @@ struct stream; #define HLUA_CTRLYIELD 0x00000002 #define HLUA_WAKERESWR 0x00000004 #define HLUA_WAKEREQWR 0x00000008 +#define HLUA_EXIT 0x00000010 enum hlua_exec { HLUA_E_OK = 0, diff --git a/src/hlua.c b/src/hlua.c index 84aee6330..5357b32fd 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -991,6 +991,16 @@ timeout_reached: break; case LUA_ERRRUN: + + /* Special exit case. The traditionnal exit is returned as an error + * because the errors ares the only one mean to return immediately + * from and lua execution. + */ + if (lua->flags & HLUA_EXIT) { + ret = HLUA_E_OK; + break; + } + lua->wake_time = TICK_ETERNITY; if (!lua_checkstack(lua->T, 1)) { ret = HLUA_E_ERR; @@ -1070,6 +1080,17 @@ timeout_reached: return ret; } +/* This function exit the current code. */ +__LJMP static int hlua_done(lua_State *L) +{ + struct hlua *hlua = hlua_gethlua(L); + + hlua->flags |= HLUA_EXIT; + WILL_LJMP(lua_error(L)); + + return 0; +} + /* This function is an LUA binding. It provides a function * for deleting ACL from a referenced ACL file. */ @@ -4704,6 +4725,7 @@ void hlua_init(void) hlua_class_function(gL.T, "Info", hlua_log_info); hlua_class_function(gL.T, "Warning", hlua_log_warning); hlua_class_function(gL.T, "Alert", hlua_log_alert); + hlua_class_function(gL.T, "done", hlua_done); lua_setglobal(gL.T, "core");