* MUST NOT manipulate the created thread stack state, because it is not
* protected against errors thrown by the thread stack.
*/
-int hlua_ctx_init(struct hlua *lua, struct task *task, int already_safe)
+int hlua_ctx_init(struct hlua *lua, lua_State *state_from, struct task *task, int already_safe)
{
if (!already_safe) {
- if (!SET_SAFE_LJMP(gL.T)) {
+ if (!SET_SAFE_LJMP(state_from)) {
lua->Tref = LUA_REFNIL;
return 0;
}
lua->flags = 0;
lua->gc_count = 0;
lua->wake_time = TICK_ETERNITY;
+ lua->state_from = state_from;
LIST_INIT(&lua->com);
- lua->T = lua_newthread(gL.T);
+ lua->T = lua_newthread(state_from);
if (!lua->T) {
lua->Tref = LUA_REFNIL;
if (!already_safe)
- RESET_SAFE_LJMP(gL.T);
+ RESET_SAFE_LJMP(state_from);
return 0;
}
hlua_sethlua(lua);
- lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
+ lua->Tref = luaL_ref(state_from, LUA_REGISTRYINDEX);
lua->task = task;
if (!already_safe)
- RESET_SAFE_LJMP(gL.T);
+ RESET_SAFE_LJMP(state_from);
return 1;
}
luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
RESET_SAFE_LJMP(lua->T);
- if (!SET_SAFE_LJMP(gL.T))
+ if (!SET_SAFE_LJMP(lua->state_from))
return;
- luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
- RESET_SAFE_LJMP(gL.T);
+ luaL_unref(lua->state_from, LUA_REGISTRYINDEX, lua->Tref);
+ RESET_SAFE_LJMP(lua->state_from);
/* Forces a garbage collecting process. If the Lua program is finished
* without error, we run the GC on the thread pointer. Its freed all
* the unused memory.
* the garbage collection.
*/
if (lua->gc_count) {
- if (!SET_SAFE_LJMP(gL.T))
+ if (!SET_SAFE_LJMP(lua->state_from))
return;
- lua_gc(gL.T, LUA_GCCOLLECT, 0);
- RESET_SAFE_LJMP(gL.T);
+ lua_gc(lua->state_from, LUA_GCCOLLECT, 0);
+ RESET_SAFE_LJMP(lua->state_from);
}
lua->T = NULL;
int new_ref;
/* New Lua coroutine. */
- T = lua_newthread(gL.T);
+ T = lua_newthread(lua->state_from);
if (!T)
return 0;
luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
/* The thread is garbage collected by Lua. */
- luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
+ luaL_unref(lua->state_from, LUA_REGISTRYINDEX, lua->Tref);
/* Fill the struct with the new coroutine values. */
lua->Mref = new_ref;
lua->T = T;
- lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
+ lua->Tref = luaL_ref(lua->state_from, LUA_REGISTRYINDEX);
/* Set context. */
hlua_sethlua(lua);
/* Call the function. */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
- ret = lua_resume(lua->T, gL.T, lua->nargs, &nres);
+ ret = lua_resume(lua->T, lua->state_from, lua->nargs, &nres);
#else
- ret = lua_resume(lua->T, gL.T, lua->nargs);
+ ret = lua_resume(lua->T, lua->state_from, lua->nargs);
#endif
switch (ret) {
struct hlua *hlua;
struct task *task;
int ref;
+ lua_State *state_from;
MAY_LJMP(check_args(L, 1, "register_task"));
ref = MAY_LJMP(hlua_checkfunction(L, 1));
+ /* Get the reference state. If the reference is NULL, L is the master
+ * state, otherwise hlua->T is.
+ */
+ hlua = hlua_gethlua(L);
+ if (hlua)
+ state_from = hlua->T;
+ else
+ state_from = L;
+
hlua = pool_alloc(pool_head_hlua);
if (!hlua)
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
task->context = hlua;
task->process = hlua_process_task;
- if (!hlua_ctx_init(hlua, task, 1))
+ if (!hlua_ctx_init(hlua, state_from, task, 1))
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
/* Restore the function in the stack. */
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
- if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
+ if (!hlua_ctx_init(stream->hlua, gL.T, stream->task, 0)) {
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
- if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
+ if (!hlua_ctx_init(stream->hlua, gL.T, stream->task, 0)) {
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
rule->arg.hlua_rule->fcn->name);
goto end;
}
- if (!hlua_ctx_init(s->hlua, s->task, 0)) {
+ if (!hlua_ctx_init(s->hlua, gL.T, s->task, 0)) {
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
rule->arg.hlua_rule->fcn->name);
goto end;
* permits to save performances because a systematic
* Lua initialization cause 5% performances loss.
*/
- if (!hlua_ctx_init(hlua, task, 0)) {
+ if (!hlua_ctx_init(hlua, gL.T, task, 0)) {
SEND_ERR(px, "Lua applet tcp '%s': can't initialize Lua context.\n",
ctx->rule->arg.hlua_rule->fcn->name);
return 0;
* permits to save performances because a systematic
* Lua initialization cause 5% performances loss.
*/
- if (!hlua_ctx_init(hlua, task, 0)) {
+ if (!hlua_ctx_init(hlua, gL.T, task, 0)) {
SEND_ERR(px, "Lua applet http '%s': can't initialize Lua context.\n",
ctx->rule->arg.hlua_rule->fcn->name);
return 0;
appctx->ctx.hlua_cli.task->process = hlua_applet_wakeup;
/* Initialises the Lua context */
- if (!hlua_ctx_init(hlua, appctx->ctx.hlua_cli.task, 0)) {
+ if (!hlua_ctx_init(hlua, gL.T, appctx->ctx.hlua_cli.task, 0)) {
SEND_ERR(NULL, "Lua cli '%s': can't initialize Lua context.\n", fcn->name);
goto error;
}