*/
static struct list referenced_functions = LIST_HEAD_INIT(referenced_functions);
+/* This variable is used only during initialization to identify the Lua state
+ * currently being initialized. 0 is the common lua state, 1 to n are the Lua
+ * states dedicated to each thread (in this case hlua_state_id==tid+1).
+ */
+static int hlua_state_id;
+
#define SET_SAFE_LJMP_L(__L, __HLUA) \
({ \
int ret; \
#endif
/* List head of the function called at the initialisation time. */
-struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
+struct list hlua_init_functions[MAX_THREADS + 1];
/* The following variables contains the reference of the different
* Lua classes. These references are useful for identify metadata
static inline struct hlua_function *new_hlua_function()
{
struct hlua_function *fcn;
+ int i;
fcn = calloc(1, sizeof(*fcn));
if (!fcn)
return NULL;
LIST_ADDQ(&referenced_functions, &fcn->l);
+ for (i = 0; i < MAX_THREADS + 1; i++)
+ fcn->function_ref[i] = -1;
return fcn;
}
+/* If the common state is set, the stack id is 0, otherwise it is the tid + 1 */
+static inline int fcn_ref_to_stack_id(struct hlua_function *fcn)
+{
+ if (fcn->function_ref[0] == -1)
+ return tid + 1;
+ return 0;
+}
+
/* Used to check an Lua function type in the stack. It creates and
* returns a reference of the function. This function throws an
* error if the rgument is not a "function".
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
init->function_ref = ref;
- LIST_ADDQ(&hlua_init_functions, &init->l);
+ LIST_ADDQ(&hlua_init_functions[hlua_state_id], &init->l);
return 0;
}
state_id = hlua->state_id;
else
/* we are in initialization mode */
- state_id = 0;
+ state_id = hlua_state_id;
hlua = pool_alloc(pool_head_hlua);
if (!hlua)
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
- if (!hlua_ctx_init(stream->hlua, 0, stream->task, 0)) {
+ if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
}
/* Restore the function in the stack. */
- lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
+ lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref[stream->hlua->state_id]);
/* convert input sample and pust-it in the stack. */
if (!lua_checkstack(stream->hlua->T, 1)) {
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
- if (!hlua_ctx_init(stream->hlua, 0, stream->task, 0)) {
+ if (!hlua_ctx_init(stream->hlua, fcn_ref_to_stack_id(fcn), stream->task, 0)) {
SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
return 0;
}
}
/* Restore the function in the stack. */
- lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
+ lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref[stream->hlua->state_id]);
/* push arguments in the stack. */
if (!hlua_txn_new(stream->hlua->T, stream, smp->px, smp->opt & SMP_OPT_DIR, hflags)) {
fcn->name = strdup(name);
if (!fcn->name)
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
- fcn->function_ref = ref;
+ fcn->function_ref[hlua_state_id] = ref;
/* List head */
sck->list.n = sck->list.p = NULL;
fcn->name = strdup(name);
if (!fcn->name)
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
- fcn->function_ref = ref;
+ fcn->function_ref[hlua_state_id] = ref;
/* List head */
sfk->list.n = sfk->list.p = NULL;
rule->arg.hlua_rule->fcn->name);
goto end;
}
- if (!hlua_ctx_init(s->hlua, 0, s->task, 0)) {
+ if (!hlua_ctx_init(s->hlua, fcn_ref_to_stack_id(rule->arg.hlua_rule->fcn), s->task, 0)) {
SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
rule->arg.hlua_rule->fcn->name);
goto end;
}
/* Restore the function in the stack. */
- lua_rawgeti(s->hlua->T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn->function_ref);
+ lua_rawgeti(s->hlua->T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn->function_ref[s->hlua->state_id]);
/* Create and and push object stream in the stack. */
if (!hlua_txn_new(s->hlua->T, s, px, dir, hflags)) {
* permits to save performances because a systematic
* Lua initialization cause 5% performances loss.
*/
- if (!hlua_ctx_init(hlua, 0, task, 0)) {
+ if (!hlua_ctx_init(hlua, fcn_ref_to_stack_id(ctx->rule->arg.hlua_rule->fcn), task, 0)) {
SEND_ERR(px, "Lua applet tcp '%s': can't initialize Lua context.\n",
ctx->rule->arg.hlua_rule->fcn->name);
return 0;
}
/* Restore the function in the stack. */
- lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn->function_ref);
+ lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn->function_ref[hlua->state_id]);
/* Create and and push object stream in the stack. */
if (!hlua_applet_tcp_new(hlua->T, ctx)) {
* permits to save performances because a systematic
* Lua initialization cause 5% performances loss.
*/
- if (!hlua_ctx_init(hlua, 0, task, 0)) {
+ if (!hlua_ctx_init(hlua, fcn_ref_to_stack_id(ctx->rule->arg.hlua_rule->fcn), task, 0)) {
SEND_ERR(px, "Lua applet http '%s': can't initialize Lua context.\n",
ctx->rule->arg.hlua_rule->fcn->name);
return 0;
}
/* Restore the function in the stack. */
- lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn->function_ref);
+ lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn->function_ref[hlua->state_id]);
/* Create and and push object stream in the stack. */
if (!hlua_applet_http_new(hlua->T, ctx)) {
fcn->name = strdup(name);
if (!fcn->name)
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
- fcn->function_ref = ref;
+ fcn->function_ref[hlua_state_id] = ref;
/* Set the expected number od arguments. */
fcn->nargs = nargs;
if (!fcn->name)
WILL_LJMP(luaL_error(L, "Lua out of memory error."));
snprintf((char *)fcn->name, len, "<lua.%s>", name);
- fcn->function_ref = ref;
+ fcn->function_ref[hlua_state_id] = ref;
/* List head */
akl->list.n = akl->list.p = NULL;
appctx->ctx.hlua_cli.task->process = hlua_applet_wakeup;
/* Initialises the Lua context */
- if (!hlua_ctx_init(hlua, 0, appctx->ctx.hlua_cli.task, 0)) {
+ if (!hlua_ctx_init(hlua, fcn_ref_to_stack_id(fcn), appctx->ctx.hlua_cli.task, 0)) {
SEND_ERR(NULL, "Lua cli '%s': can't initialize Lua context.\n", fcn->name);
goto error;
}
}
/* Restore the function in the stack. */
- lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
+ lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, fcn->function_ref[hlua->state_id]);
/* Once the arguments parsed, the CLI is like an AppletTCP,
* so push AppletTCP in the stack.
strncat((char *)fcn->name, cli_kws->kw[0].str_kw[i], len);
}
strncat((char *)fcn->name, ">", len);
- fcn->function_ref = ref_io;
+ fcn->function_ref[hlua_state_id] = ref_io;
/* Fill last entries. */
cli_kws->kw[0].private = fcn;
return -1;
}
+ hlua_state_id = 0;
return hlua_load_state(args[1], hlua_states[0], err);
}
hlua_fcn_post_init(L);
- list_for_each_entry(init, &hlua_init_functions, l) {
+ list_for_each_entry(init, &hlua_init_functions[hlua_state_id], l) {
lua_rawgeti(L, LUA_REGISTRYINDEX, init->function_ref);
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
}
#endif
- return hlua_post_init_state(hlua_states[0]);
+ /* Perform post init of common thread */
+ hlua_state_id = 0;
+ return hlua_post_init_state(hlua_states[hlua_state_id]);
}
/* The memory allocator used by the Lua stack. <ud> is a pointer to the
}
void hlua_init(void) {
+ int i;
+
+ /* Init post init function list head */
+ for (i = 0; i < MAX_THREADS + 1; i++)
+ LIST_INIT(&hlua_init_functions[i]);
+
+ /* Init state for common/shared lua parts */
+ hlua_state_id = 0;
hlua_states[0] = hlua_init_state(0);
}