cast and freed. The const char* is here to leave more freedom to use consts
when making such options lists.
+- void hap_register_hlua_state_init(int (*fct)())
+
+ This adds a call to function <fct> to the list of functions to be called each
+ time a new Lua state is created by hlua_init_state(). This allows source
+ files other than hlua.c to register objects and functions into the Lua API
+ without modifying hlua.c directly. The function <fct> must return an ERR_*
+ code. If the errmsg pointer is set on return, it is printed as an alert,
+ warning, or notice depending on the error code. If ERR_ABORT or ERR_FATAL is
+ returned, haproxy will exit with status 1.
+
- void hap_register_per_thread_alloc(int (*fct)())
This adds a call to function <fct> to the list of functions to be called when
is that it allows to register multiple <post> callbacks and to register them
elsewhere in the code.
+- REGISTER_HLUA_STATE_INIT(fct)
+
+ Registers function <fct> to be called for each new Lua state created by
+ hlua_init_state(). This allows source files other than hlua.c to register
+ objects and functions into the Lua API without modifying hlua.c directly.
+ This is done by registering a call to hap_register_hlua_state_init(fct) at
+ stage STG_REGISTER. The function <fct> must be of type
+ (int (*fct)(lua_State *L, char **errmsg)) and must return an ERR_* code.
+ If the errmsg pointer is set on return, it is printed as an alert, warning,
+ or notice depending on the error code. If ERR_ABORT or ERR_FATAL is returned,
+ haproxy will exit with status 1.
+
- REGISTER_PER_THREAD_ALLOC(fct)
Registers a call to register_per_thread_alloc(fct) at stage STG_REGISTER.
struct pat_ref_gen *gen; /* the generation we are iterating over */
};
+struct hlua_state_init_fct {
+ struct list list;
+ int (*fct)(lua_State *L, char **errmsg);
+};
+
#else /* USE_LUA */
/************************ For use when Lua is disabled ********************/
/* Lua HAProxy integration functions. */
void hlua_yield_asap(lua_State *L);
+void hap_register_hlua_state_init(int (*fct)(lua_State *L, char **errmsg));
+
+/* simplified way to register a lua_State init callback from any file */
+#define REGISTER_HLUA_STATE_INIT(fct) \
+ INITCALL1(STG_REGISTER, hap_register_hlua_state_init, (fct))
const char *hlua_traceback(lua_State *L, const char* sep);
void hlua_ctx_destroy(struct hlua *lua);
void hlua_init();
*/
static struct list referenced_functions = LIST_HEAD_INIT(referenced_functions);
+/* List of callbacks registered via hap_register_hlua_state_init(), called
+ * for each new lua_State created in hlua_init_state().
+ */
+static struct list hlua_state_init_list = LIST_HEAD_INIT(hlua_state_init_list);
+
+void hap_register_hlua_state_init(int (*fct)(lua_State *L, char **errmsg))
+{
+ struct hlua_state_init_fct *entry;
+
+ entry = calloc(1, sizeof(*entry));
+ if (!entry) {
+ ha_alert("hlua: out of memory registering state init callback\n");
+ exit(1);
+ }
+ entry->fct = fct;
+ LIST_APPEND(&hlua_state_init_list, &entry->list);
+}
+
/* 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).
/* Register previous table in the registry with reference and named entry. */
class_socket_ref = hlua_register_metatable(L, CLASS_SOCKET);
+ /* Call all registered state init callbacks. */
+ {
+ struct hlua_state_init_fct *e;
+ char *errmsg = NULL;
+ int err_code;
+
+ list_for_each_entry(e, &hlua_state_init_list, list) {
+ err_code = e->fct(L, &errmsg);
+ if (errmsg) {
+ if (err_code & ERR_ALERT)
+ ha_alert("Lua: %s\n", errmsg);
+ else if (err_code & ERR_WARN)
+ ha_warning("Lua: %s\n", errmsg);
+ else
+ ha_notice("Lua: %s\n", errmsg);
+ ha_free(&errmsg);
+ }
+ if (err_code & (ERR_ABORT|ERR_FATAL))
+ exit(1);
+ }
+ }
+
lua_atpanic(L, hlua_panic_safe);
return L;
{
int thr;
struct hlua_reg_filter *reg_flt, *reg_flt_bck;
+ struct hlua_state_init_fct *e, *eb;
list_for_each_entry_safe(reg_flt, reg_flt_bck, &referenced_filters, l)
release_hlua_reg_filter(reg_flt);
+ list_for_each_entry_safe(e, eb, &hlua_state_init_list, list) {
+ LIST_DELETE(&e->list);
+ free(e);
+ }
+
for (thr = 0; thr < MAX_THREADS+1; thr++) {
if (hlua_states[thr])
lua_close(hlua_states[thr]);