From be165549d1dfe25a0c3badadf449aa48e4a349e6 Mon Sep 17 00:00:00 2001 From: niubinghui Date: Mon, 14 Oct 2024 19:04:56 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=96=B0=E6=8E=A5=E5=8F=A3=E4=BB=A3=E7=A0=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=8C=E9=80=9A=E8=BF=87=E7=BC=96=E8=AF=91=E6=9C=AA?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/lua_module_manage.h | 16 + src/Makefile | 14 +- src/lua_binding_cfunc.c | 116 ++++ src/lua_binding_cfunc.h | 17 + src/lua_binding_function.c | 1017 +++++++++++++----------------- src/lua_binding_function.h | 69 +- src/lua_module_manage.c | 137 ++++ src/lua_module_manage_internal.c | 862 +++++++++++++++++++++++++ src/lua_module_manage_internal.h | 231 +++++++ src/lua_plugin_cfunc.c | 201 ------ src/lua_plugin_manage.c | 931 --------------------------- src/lua_plugin_manage_internal.h | 217 ------- 12 files changed, 1835 insertions(+), 1993 deletions(-) create mode 100644 include/lua_module_manage.h create mode 100644 src/lua_binding_cfunc.c create mode 100644 src/lua_binding_cfunc.h create mode 100644 src/lua_module_manage.c create mode 100644 src/lua_module_manage_internal.c create mode 100644 src/lua_module_manage_internal.h delete mode 100644 src/lua_plugin_cfunc.c delete mode 100644 src/lua_plugin_manage.c delete mode 100644 src/lua_plugin_manage_internal.h diff --git a/include/lua_module_manage.h b/include/lua_module_manage.h new file mode 100644 index 0000000..ea0d7ca --- /dev/null +++ b/include/lua_module_manage.h @@ -0,0 +1,16 @@ +#pragma once + +#include "stellar/module_manager.h" + +#define LUA_MODULE_MANAGE_MODULE_NAME "lua_moduel_manager_module" +#define LUA_MODULE_MANAGE_CONF_PATH "lua_module_manage.toml" + +typedef void lua_mq_on_msg_cb_func(int topic_id, void *msg, void *on_msg_arg, void *after_dispatch_arg); + +struct stellar_module *lua_module_manager_on_init(struct stellar_module_manager *mod_mgr); +void lua_module_manager_on_exit(struct stellar_module_manager *mod_mgr, struct stellar_module *mod); + + +/* 提供的通用函数 */ +/* 通用的Lua mq订阅函数, on_msg */ +/* 注册新数据及自定义函数的接口,能够传参或获取返回值 */ \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index a9b8b6c..4385424 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,13 +5,15 @@ TARGET=libluaplugin.so # TEST_FLAG = -DLUAPLUGIN_BASIC_UNITTEST -SRC := lua_plugin_cfunc.c \ +SRC := lua_module_manage_internal.c \ + lua_binding_cfunc.c \ lua_binding_function.c \ - lua_plugin_manage.c + lua_module_manage.c -OBJECTS := lua_plugin_cfunc.o \ +OBJECTS := lua_module_manage_internal.o \ + lua_binding_cfunc.o \ lua_binding_function.o \ - lua_plugin_manage.o + lua_module_manage.o INCLUDE = -I$(TOPDIR)/dependence/include -I$(TOPDIR)/include CFLAGS = -g -Wextra -Wall -O0 -fPIC @@ -20,8 +22,8 @@ LDLIBS = -L$(TOPDIR)/dependence/lib -llua -ltoml -lplugin_manager -ldl -lm all:$(OBJECTS) $(CC) $(CFLAGS) -shared -o $(TARGET) $(OBJECTS) $(LDLIBS) - mkdir -p $(TOPDIR)/output/libs - cp -f $(TARGET) $(TOPDIR)/output/libs + # mkdir -p $(TOPDIR)/output/libs + # cp -f $(TARGET) $(TOPDIR)/output/libs $(OBJECTS):$(SRC) $(CC) $(TEST_FLAG) $(INCLUDE) $(CFLAGS) $(SRC) -c $^ diff --git a/src/lua_binding_cfunc.c b/src/lua_binding_cfunc.c new file mode 100644 index 0000000..fb26ab7 --- /dev/null +++ b/src/lua_binding_cfunc.c @@ -0,0 +1,116 @@ +#include "lua_binding_cfunc.h" +#include "lua_module_manage_internal.h" + +static inline struct lua_state *lua_fn_arg_pair_get_thread_state(struct lua_fn_arg_pair *pair) +{ + struct lua_module_manager *lua_mod_mgr = pair->lua_mod_mgr; + int thread_id = stellar_module_manager_get_thread_id(lua_mod_mgr->mod_mgr); + return lua_mod_mgr->state_array[thread_id]; +} + +void lua_manager_mq_msg_free_cb_func(void *msg, void *msg_free_arg) +{ + if (!msg_free_arg) + return; + struct lua_fn_arg_pair *free_arg = (struct lua_fn_arg_pair *)msg_free_arg; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(free_arg); + + struct lua_cdata param[2]; + if (lua_context_check_if_context(msg)) + lua_cdata_data_set(¶m[0], DATATYPE_CONTEXT, msg, 0); + else + lua_cdata_data_set(¶m[0], DATATYPE_POINTER, msg, 0); + lua_cdata_data_set(¶m[1], DATATYPE_TABLE, NULL, free_arg->lua_arg_ref_id); + + lua_chunk_execute(state, free_arg->lua_fn_ref_id, param, 2, NULL, 0, NULL, 0); + return; +} + +void lua_manager_mq_on_msg_cb_func(int topic_id, void *msg, void *on_msg_arg) +{ + if (!on_msg_arg) + return; + struct lua_fn_arg_pair *msg_arg = (struct lua_fn_arg_pair *)on_msg_arg; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(msg_arg); + + struct lua_cdata param[3]; + lua_cdata_data_set(¶m[0], DATATYPE_INT, NULL, topic_id); + if (lua_context_check_if_context(msg)) + lua_cdata_data_set(¶m[1], DATATYPE_CONTEXT, msg, 0); + else + lua_cdata_data_set(¶m[1], DATATYPE_POINTER, msg, 0); + lua_cdata_data_set(¶m[2], DATATYPE_TABLE, NULL, msg_arg->lua_arg_ref_id); + + lua_chunk_execute(state, msg_arg->lua_fn_ref_id, param, 3, NULL, 0, NULL, 0); + return; +} + +void lua_manager_mq_on_msg_dispatch_cb_func(int topic_id, void *msg, on_msg_cb_func *on_msg_cb, void *on_msg_cb_arg, void *dispatch_arg) +{ + if (!dispatch_arg) + return; + struct lua_fn_arg_pair *dis_arg = (struct lua_fn_arg_pair *)dispatch_arg; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(dis_arg); + + struct lua_cdata param[4]; + struct lua_context *new_context = lua_context_new(state); + lua_cdata_data_set(¶m[0], DATATYPE_INT, NULL, topic_id); + lua_cdata_data_set(¶m[1], DATATYPE_CONTEXT, msg, 0); + lua_cdata_data_set(¶m[2], DATATYPE_TABLE, 0, dis_arg->lua_arg_ref_id); + lua_cdata_data_set(¶m[3], DATATYPE_CONTEXT, (void *)new_context, 0); + + lua_chunk_execute(state, dis_arg->lua_fn_ref_id, param, 4, NULL, 0, NULL, 0); + ((lua_mq_on_msg_cb_func *)(void *)on_msg_cb)(topic_id, msg, on_msg_cb_arg, (void *)new_context); + + lua_context_free(new_context); + return; +} + +void lua_manager_packet_on_stage_callback(enum packet_stage stage, struct packet *pkt, void *args) +{ + if (!args) + return; + struct lua_fn_arg_pair *on_stage_callback = (struct lua_fn_arg_pair *)args; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(on_stage_callback); + + struct lua_cdata param[3]; + lua_cdata_data_set(¶m[0], DATATYPE_INT, NULL, stage); + lua_cdata_data_set(¶m[1], DATATYPE_POINTER, pkt, 0); + lua_cdata_data_set(¶m[2], DATATYPE_TABLE, NULL, on_stage_callback->lua_arg_ref_id); + + lua_chunk_execute(state, on_stage_callback->lua_fn_ref_id, param, 3, NULL, 0, NULL, 0); + return; +} + +void lua_manager_session_callback(struct session *sess, struct packet *pkt, void *args) +{ + if (!args) + return; + struct lua_fn_arg_pair *sess_callback = (struct lua_fn_arg_pair *)args; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(sess_callback); + + struct lua_cdata param[3]; + lua_cdata_data_set(¶m[0], DATATYPE_POINTER, sess, 0); + lua_cdata_data_set(¶m[1], DATATYPE_POINTER, pkt, 0); + lua_cdata_data_set(¶m[2], DATATYPE_TABLE, NULL, sess_callback->lua_arg_ref_id); + + lua_chunk_execute(state, sess_callback->lua_fn_ref_id, param, 3, NULL, 0, NULL, 0); + return; +} + +void lua_manager_tcp_stream_callback(struct session *sess, const char *tcp_payload, uint32_t tcp_payload_len, void *args) +{ + if (!args) + return; + struct lua_fn_arg_pair *tcp_stream_callback = (struct lua_fn_arg_pair *)args; + struct lua_state *state = lua_fn_arg_pair_get_thread_state(tcp_stream_callback); + + struct lua_cdata param[4]; + lua_cdata_data_set(¶m[0], DATATYPE_POINTER, sess, 0); + lua_cdata_data_set(¶m[1], DATATYPE_BUFF, (void *)tcp_payload, (int)tcp_payload_len); + lua_cdata_data_set(¶m[2], DATATYPE_INT, NULL, (int)tcp_payload_len); + lua_cdata_data_set(¶m[3], DATATYPE_TABLE, NULL, tcp_stream_callback->lua_arg_ref_id); + + lua_chunk_execute(state, tcp_stream_callback->lua_fn_ref_id, param, 3, NULL, 0, NULL, 0); + return; +} diff --git a/src/lua_binding_cfunc.h b/src/lua_binding_cfunc.h new file mode 100644 index 0000000..5704c03 --- /dev/null +++ b/src/lua_binding_cfunc.h @@ -0,0 +1,17 @@ +#ifndef LUA_MODULE_MANAGE_BINDING_CFUNC_H +#define LUA_MODULE_MANAGE_BINDING_CFUNC_H + +#include "stellar/module_manager.h" +#include "stellar/packet_manager.h" +#include "stellar/session_manager.h" + +void lua_manager_mq_msg_free_cb_func(void *msg, void *msg_free_arg); +void lua_manager_mq_on_msg_cb_func(int topic_id, void *msg, void *on_msg_arg); +void lua_manager_mq_on_msg_dispatch_cb_func(int topic_id, void *msg, on_msg_cb_func *on_msg_cb, void *on_msg_cb_arg, void *dispatch_arg); + +void lua_manager_packet_on_stage_callback(enum packet_stage stage, struct packet *pkt, void *args); + +void lua_manager_session_callback(struct session *sess, struct packet *pkt, void *args); +void lua_manager_tcp_stream_callback(struct session *sess, const char *tcp_payload, uint32_t tcp_payload_len, void *args); + +#endif \ No newline at end of file diff --git a/src/lua_binding_function.c b/src/lua_binding_function.c index c308c41..f9ef35c 100644 --- a/src/lua_binding_function.c +++ b/src/lua_binding_function.c @@ -1,240 +1,54 @@ +#include "lua_binding_function.h" +#include "lua_binding_cfunc.h" + +#include "stellar/mq.h" +#include "stellar/module_manager.h" +#include "stellar/packet.h" +#include "stellar/packet_manager.h" +#include "stellar/session.h" +#include "stellar/session_manager.h" +#include "stellar/utils.h" + #include #include - -#include -#include #include +#include +#include +#include -#include "lua_binding_function.h" - -/* ***** ***** ***** ***** ***** ***** */ -int lua_get_worker_thread_num(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 1) - { - lua_settop(L, 0); - return 0; - } - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - int thread_num = stellar_get_worker_thread_num(st); - lua_pushinteger(L, thread_num); - return 1; -} - -int lua_get_current_thread_id(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 1) - { - lua_settop(L, 0); - return 0; - } - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - int thread_id = stellar_get_current_thread_id(st); - lua_pushinteger(L, thread_id); - return 1; -} - -int lua_get_stellar_pointer(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - lua_settop(L, 0); - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - struct stellar *st = plugin_manage->st; - lua_pushlightuserdata(L, (void *)st); - return 1; -} - -/* -int lua_get_plugin_manage_pointer(struct lua_state *state) -{ - lua_settop((lua_State *)state, 0); - struct lua_plugin_manage * plugin_manage = lua_state_get_plugin_manage(state); - lua_pushlightuserdata((lua_State *)state, (void *)plugin_manage); - return 1; -} -*/ - -/* ***** ***** ***** ***** ***** ***** */ -int lua_session_plugin_regist(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4 || lua_type(L, -4) != LUA_TLIGHTUSERDATA) - { - lua_settop(L, 0); - return 0; +#define LUA_BINDING_FUNCTION_GET_VALUE_POINTER(func_name, param_type, value_type, value_func) \ + int func_name(struct lua_state *state) \ + { \ + lua_State *L = (lua_State *)state; \ + if (lua_gettop(L) != 1) \ + { \ + lua_settop(L, 0); \ + return 0; \ + } \ + param_type *p = (param_type *)lua_topointer(L, -1); \ + lua_settop(L, 0); \ + value_type *l = (value_type *)value_func(p); \ + lua_pushlightuserdata(L, (void *)l); \ + return 1; \ } - /* stack -1 */ - int plugin_env_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (plugin_env_ref_id == LUA_REFNIL) - plugin_env_ref_id = 0; - - /* stack -2 */ - int ctx_free_fn_ref_id = 0; - if (lua_type(L, -1) == LUA_TFUNCTION) - ctx_free_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - else - lua_pop(L, 1); - - /* stack -3 */ - int ctx_new_fn_ref_id = 0; - if (lua_type(L, -1) == LUA_TFUNCTION) - ctx_new_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - else - lua_pop(L, 1); - - /* stack -4 */ - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - - struct lua_session_plugin_env *new_plugin_env = (struct lua_session_plugin_env *)calloc(1, sizeof(struct lua_session_plugin_env)); - memset(new_plugin_env, 0, sizeof(struct lua_session_plugin_env)); - new_plugin_env->lua_ctx_new_fn_ref_id = ctx_new_fn_ref_id; - new_plugin_env->lua_ctx_free_fn_ref_id = ctx_free_fn_ref_id; - new_plugin_env->lua_plug_env_ref_id = plugin_env_ref_id; - - int plugin_id = stellar_session_plugin_register(st, lpm_ctx_new_func, lpm_ctx_free_func, (void *)new_plugin_env); - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - LL_APPEND(plugin_manage->session_plugin_env_list, new_plugin_env); - new_plugin_env->plugin_manage = plugin_manage; - new_plugin_env->session_plugin_id = plugin_id; - - lua_settop(L, 0); - lua_pushinteger(L, plugin_id); - - return 1; -} - -int lua_packet_plugin_regist(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4 || lua_type(L, -4) != LUA_TLIGHTUSERDATA) - { - lua_settop(L, 0); - return 0; +#define LUA_BINDING_FUNCTION_GET_VALUE_INT(func_name, param_type, value_func) \ + int func_name(struct lua_state *state) \ + { \ + lua_State *L = (lua_State *)state; \ + if (lua_gettop(L) != 1) \ + { \ + lua_settop(L, 0); \ + return 0; \ + } \ + param_type *p = (param_type *)lua_topointer(L, -1); \ + lua_settop(L, 0); \ + int v = (int)value_func(p); \ + lua_pushinteger(L, v); \ + return 1; \ } - /* stack -1 */ - int plugin_env_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (plugin_env_ref_id == LUA_REFNIL) - plugin_env_ref_id = 0; - - /* stack -2 */ - int on_packet_fn_ref_id = 0; - if (lua_type(L, -1) == LUA_TFUNCTION) - on_packet_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - else - lua_pop(L, 1); - - /* stack -3 */ - int ip_protocol = lua_tointeger(L, -1); - lua_pop(L, 1); - - /* stack -4 */ - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - - struct lua_packet_plugin_env *new_plugin_env = (struct lua_packet_plugin_env *)calloc(1, sizeof(struct lua_packet_plugin_env)); - memset(new_plugin_env, 0, sizeof(struct lua_packet_plugin_env)); - new_plugin_env->lua_plug_env_ref_id = plugin_env_ref_id; - new_plugin_env->lua_on_packet_fn_ref_id = on_packet_fn_ref_id; - - int plugin_id = stellar_packet_plugin_register(st, (unsigned char)ip_protocol, lpm_on_packet_func, (void *)new_plugin_env); - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - LL_APPEND(plugin_manage->packet_plugin_env_list, new_plugin_env); - new_plugin_env->plugin_manage = plugin_manage; - new_plugin_env->packet_plugin_id = plugin_id; - - lua_settop(L, 0); - lua_pushinteger(L, plugin_id); - - return 1; -} - -/* ***** ***** ***** ***** ***** ***** */ -int lua_session_get_type(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 1 || lua_type(L, -1) != LUA_TLIGHTUSERDATA) - { - lua_settop(L, 0); - return 0; - } - - struct session *sess = (struct session *)lua_topointer(L, -1); - lua_settop(L, 0); - if (!sess) - return 0; - - lua_pushinteger(L, (int)session_get_type(sess)); - return 1; -} - -/* ***** ***** ***** ***** ***** ***** */ -#define MQ_TYPE_PACKET 1 -#define MQ_TYPE_SESSION 2 -static int lua_plugin_manage_msg_mq_create_topic(struct lua_state *state, int type) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4 || lua_type(L, -3) != LUA_TSTRING || lua_type(L, -4) != LUA_TLIGHTUSERDATA) - { - lua_settop(L, 0); - return 0; - } - - /* stack -1 */ - int free_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (free_arg_ref_id == LUA_REFNIL) - free_arg_ref_id = 0; - - /* stack -2 */ - int free_fn_ref_id = 0; - if (lua_type(L, -1) == LUA_TFUNCTION) - free_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - else - lua_pop(L, 1); - - /* stack -3 */ - char *topic_name = strdup((char *)lua_tostring(L, -1)); - lua_pop(L, 1); - - /* stack -4 */ - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - - struct lua_message_free_arg *new_message_free_arg = (struct lua_message_free_arg *)calloc(1, sizeof(struct lua_message_free_arg)); - memset(new_message_free_arg, 0, sizeof(struct lua_message_free_arg)); - new_message_free_arg->lua_msg_free_fn_ref_id = free_fn_ref_id; - new_message_free_arg->lua_msg_free_arg_ref_id = free_arg_ref_id; - int topic_id = -1; - if (type == MQ_TYPE_PACKET) - topic_id = stellar_packet_mq_create_topic(st, (const char *)topic_name, lpm_packet_message_free_func, new_message_free_arg); - else if (type == MQ_TYPE_SESSION) - topic_id = stellar_session_mq_create_topic(st, (const char *)topic_name, lpm_session_message_free_func, new_message_free_arg); - if (topic_id >= 0) - { - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - LL_APPEND(plugin_manage->message_free_arg_list, new_message_free_arg); - new_message_free_arg->topic_id = topic_id; - new_message_free_arg->plugin_manage = plugin_manage; - lua_pop(L, 1); - } - else - { - if (new_message_free_arg) - free(new_message_free_arg); - return 0; - } - - lua_pushinteger(L, topic_id); - return 1; -} - -static int lua_plugin_manage_msg_mq_get_topic_id(struct lua_state *state, int type) +int lua_mq_schema_get_topic_id(struct lua_state *state) { lua_State *L = (lua_State *)state; if (lua_gettop(L) != 2 || lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TLIGHTUSERDATA) @@ -245,427 +59,444 @@ static int lua_plugin_manage_msg_mq_get_topic_id(struct lua_state *state, int ty char *topic_name = strdup(lua_tostring(L, -1)); lua_pop(L, 1); - struct stellar *st = (struct stellar *)lua_topointer(L, -1); + struct mq_schema *s = (struct mq_schema *)lua_topointer(L, -1); lua_settop(L, 0); - int topic_id = -1; - if (type == MQ_TYPE_PACKET) - topic_id = stellar_packet_mq_get_topic_id(st, (const char *)topic_name); - else if (type == MQ_TYPE_SESSION) - topic_id = stellar_session_mq_get_topic_id(st, (const char *)topic_name); + int topic_id = mq_schema_get_topic_id(s, (const char *)topic_name); + if (topic_name) - free(topic_name); + FREE(topic_name); + lua_pushinteger(L, topic_id); + return 1; +} + +int lua_mq_schema_create_topic(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + if (lua_gettop(L) != 6 || lua_type(L, -5) != LUA_TSTRING || lua_type(L, -6) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } + + int free_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int free_cb_fn_ref_id = -1; + if (lua_type(L, -1) == LUA_TFUNCTION) + free_cb_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + else + lua_pop(L, 1); + int on_dispatch_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_dispatch_cb_fn_ref_id = -1; + if (lua_type(L, -1) == LUA_TFUNCTION) + on_dispatch_cb_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + else + lua_pop(L, 1); + char *topic_name = strdup((char *)lua_tostring(L, -1)); + lua_pop(L, 1); + struct mq_schema *s = (struct mq_schema *)lua_topointer(L, -1); + lua_settop(L, 0); + + struct lua_fn_arg_pair *new_mq_dispatch_arg = CALLOC(struct lua_fn_arg_pair, 1); + memset(new_mq_dispatch_arg, 0, sizeof(struct lua_fn_arg_pair)); + new_mq_dispatch_arg->lua_fn_ref_id = on_dispatch_cb_fn_ref_id; + new_mq_dispatch_arg->lua_arg_ref_id = on_dispatch_arg_ref_id; + struct lua_fn_arg_pair *new_mq_msg_free_arg = CALLOC(struct lua_fn_arg_pair, 1); + memset(new_mq_msg_free_arg, 0, sizeof(struct lua_fn_arg_pair)); + new_mq_msg_free_arg->lua_fn_ref_id = free_cb_fn_ref_id; + new_mq_msg_free_arg->lua_arg_ref_id = free_arg_ref_id; + int topic_id = mq_schema_create_topic(s, + (const char *)topic_name, + lua_manager_mq_on_msg_dispatch_cb_func, + new_mq_dispatch_arg, + lua_manager_mq_msg_free_cb_func, + new_mq_msg_free_arg); + if (topic_id >= 0) + { + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_mq_dispatch_arg->lua_mod_mgr = lua_mod_mgr; + new_mq_msg_free_arg->lua_mod_mgr = lua_mod_mgr; + LL_APPEND(lua_mod_mgr->mq_dispatch_list, new_mq_dispatch_arg); + LL_APPEND(lua_mod_mgr->mq_msg_free_list, new_mq_msg_free_arg); + } + else + { + if (free_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, free_arg_ref_id); + if (free_cb_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, free_cb_fn_ref_id); + if (on_dispatch_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_dispatch_arg_ref_id); + if (on_dispatch_cb_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_dispatch_cb_fn_ref_id); + if (new_mq_dispatch_arg) + FREE(new_mq_dispatch_arg); + if (new_mq_msg_free_arg) + FREE(new_mq_msg_free_arg); + } lua_pushinteger(L, topic_id); return 1; } -static int lua_plugin_manage_msg_mq_update_topic(struct lua_state *state, int type) +int lua_mq_schema_update_topic(struct lua_state *state) { lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4 || lua_type(L, -3) != LUA_TNUMBER || lua_type(L, -4) != LUA_TLIGHTUSERDATA) - goto err; + if (lua_gettop(L) != 6 || lua_type(L, -5) != LUA_TNUMBER || lua_type(L, -6) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } - /* stack -1 */ int free_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (free_arg_ref_id == LUA_REFNIL) - free_arg_ref_id = 0; - - /* stack -2 */ - int free_fn_ref_id = 0; + int free_cb_fn_ref_id = -1; if (lua_type(L, -1) == LUA_TFUNCTION) - free_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + free_cb_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); else lua_pop(L, 1); - - /* stack -3 */ - int topic_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - /* stack -4 */ - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - - struct lua_message_free_arg *new_message_free_arg = (struct lua_message_free_arg *)calloc(1, sizeof(struct lua_message_free_arg)); - memset(new_message_free_arg, 0, sizeof(struct lua_message_free_arg)); - new_message_free_arg->topic_id = topic_id; - new_message_free_arg->lua_msg_free_fn_ref_id = free_fn_ref_id; - new_message_free_arg->lua_msg_free_arg_ref_id = free_arg_ref_id; - int update_result = -1; - if (type == MQ_TYPE_PACKET) - update_result = stellar_packet_mq_update_topic(st, topic_id, lpm_packet_message_free_func, new_message_free_arg); - else if (type == MQ_TYPE_SESSION) - update_result = stellar_session_mq_update_topic(st, topic_id, lpm_session_message_free_func, new_message_free_arg); - if (update_result) - { - if (new_message_free_arg) - free(new_message_free_arg); - goto err; - } - - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - new_message_free_arg->plugin_manage = plugin_manage; - LL_APPEND(plugin_manage->message_free_arg_list, new_message_free_arg); - lua_settop(L, 0); - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - return 1; -} - -static int lua_plugin_manage_msg_mq_destory_topic(struct lua_state *state, int type) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 2) - goto err; - - int topic_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - struct stellar *st = (struct stellar *)lua_topointer(L, -1); - lua_settop(L, 0); - - int destory_result = -1; - if (type == MQ_TYPE_PACKET) - destory_result = stellar_packet_mq_destroy_topic(st, topic_id); - else if (type == MQ_TYPE_SESSION) - destory_result = stellar_session_mq_destroy_topic(st, topic_id); - if (destory_result < 0) - goto err; - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - return 1; -} - -static int lua_plugin_manage_msg_mq_subscribe_topic(struct lua_state *state, int type) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4 || lua_type(L, -4) != LUA_TLIGHTUSERDATA) - goto err; - - int plugin_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - int on_message_fn_ref_id = 0; + int on_dispatch_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_dispatch_cb_fn_ref_id = -1; if (lua_type(L, -1) == LUA_TFUNCTION) - on_message_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + on_dispatch_cb_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); else lua_pop(L, 1); - int topic_id = lua_tointeger(L, -1); lua_pop(L, 1); - struct stellar *st = (struct stellar *)lua_topointer(L, -1); + struct mq_schema *s = (struct mq_schema *)lua_topointer(L, -1); lua_settop(L, 0); - int subscribe_result = -1; - if (type == MQ_TYPE_PACKET) - subscribe_result = stellar_packet_mq_subscribe(st, topic_id, lpm_on_packet_msg_func, plugin_id); - else if (type == MQ_TYPE_SESSION) - subscribe_result = stellar_session_mq_subscribe(st, topic_id, lpm_on_session_msg_func, plugin_id); - if (subscribe_result) - goto err; - - struct lua_on_message_fn *on_message = NULL; - struct lua_plugin_manage *plugin_manage = lua_state_get_plugin_manage(state); - if (type == MQ_TYPE_PACKET) - on_message = hash_find_on_msg_fn(plugin_manage->on_packet_message_hashlist, topic_id, plugin_id); - else if (type == MQ_TYPE_SESSION) - on_message = hash_find_on_msg_fn(plugin_manage->on_session_message_hashlist, topic_id, plugin_id); - if (on_message) + struct lua_fn_arg_pair *new_mq_dispatch_arg = CALLOC(struct lua_fn_arg_pair, 1); + memset(new_mq_dispatch_arg, 0, sizeof(struct lua_fn_arg_pair)); + new_mq_dispatch_arg->lua_fn_ref_id = on_dispatch_cb_fn_ref_id; + new_mq_dispatch_arg->lua_arg_ref_id = on_dispatch_arg_ref_id; + struct lua_fn_arg_pair *new_mq_msg_free_arg = CALLOC(struct lua_fn_arg_pair, 1); + memset(new_mq_msg_free_arg, 0, sizeof(struct lua_fn_arg_pair)); + new_mq_msg_free_arg->lua_fn_ref_id = free_cb_fn_ref_id; + new_mq_msg_free_arg->lua_arg_ref_id = free_arg_ref_id; + int update_ret = mq_schema_update_topic(s, + topic_id, + lua_manager_mq_on_msg_dispatch_cb_func, + new_mq_dispatch_arg, + lua_manager_mq_msg_free_cb_func, + new_mq_msg_free_arg); + if (topic_id) { - on_message->lua_on_msg_fn_ref_id = on_message_fn_ref_id; + if (free_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, free_arg_ref_id); + if (free_cb_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, free_cb_fn_ref_id); + if (on_dispatch_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_dispatch_arg_ref_id); + if (on_dispatch_cb_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_dispatch_cb_fn_ref_id); + if (new_mq_dispatch_arg) + FREE(new_mq_dispatch_arg); + if (new_mq_msg_free_arg) + FREE(new_mq_msg_free_arg); } else { - if (type == MQ_TYPE_PACKET) - on_message = hash_on_msg_fn_insert(plugin_manage->on_packet_message_hashlist, topic_id, plugin_id); - else if (type == MQ_TYPE_SESSION) - on_message = hash_on_msg_fn_insert(plugin_manage->on_session_message_hashlist, topic_id, plugin_id); - if (!on_message) - goto err; - else - on_message->lua_on_msg_fn_ref_id = on_message_fn_ref_id; + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_mq_dispatch_arg->lua_mod_mgr = lua_mod_mgr; + new_mq_msg_free_arg->lua_mod_mgr = lua_mod_mgr; + LL_APPEND(lua_mod_mgr->mq_dispatch_list, new_mq_dispatch_arg); + LL_APPEND(lua_mod_mgr->mq_msg_free_list, new_mq_msg_free_arg); } - lua_settop(L, 0); - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); + lua_pushinteger(L, update_ret); return 1; } -static int lua_plugin_manage_msg_mq_publish_message(struct lua_state *state, int type) +int lua_mq_shcema_destory_topic(struct lua_state *state) { lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 3) - goto err; + if (lua_gettop(L) != 2 || lua_type(L, -1) != LUA_TNUMBER || lua_type(L, -2) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } + + int topic_id = lua_tointeger(L, -1); + lua_pop(L, 1); + struct mq_schema *s = (struct mq_schema *)lua_topointer(L, -1); + lua_settop(L, 0); + + int destory_ret = mq_schema_destroy_topic(s, topic_id); + + lua_pushinteger(L, destory_ret); + return 1; +} + +int lua_mq_schema_subscribe(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + if (lua_gettop(L) != 4 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -4) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } + + int on_msg_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_msg_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int topic_id = lua_tointeger(L, -1); + lua_pop(L, 1); + struct mq_schema *s = (struct mq_schema *)lua_topointer(L, -1); + lua_settop(L, 0); + + struct lua_fn_arg_pair *new_mq_on_msg_arg = CALLOC(struct lua_fn_arg_pair, 1); + memset(new_mq_on_msg_arg, 0, sizeof(struct lua_fn_arg_pair)); + new_mq_on_msg_arg->lua_arg_ref_id = on_msg_arg_ref_id; + new_mq_on_msg_arg->lua_fn_ref_id = on_msg_fn_ref_id; + int subscribe_ret = mq_schema_subscribe(s, topic_id, lua_manager_mq_on_msg_cb_func, new_mq_on_msg_arg); + if (subscribe_ret) + { + if (on_msg_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_msg_arg_ref_id); + if (on_msg_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_msg_fn_ref_id); + if (new_mq_on_msg_arg) + FREE(new_mq_on_msg_arg); + } + else + { + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_mq_on_msg_arg->lua_mod_mgr = lua_mod_mgr; + LL_APPEND(lua_mod_mgr->mq_on_msg_list, new_mq_on_msg_arg); + } + + lua_pushinteger(L, subscribe_ret); + return 1; +} + +int lua_mq_runtime_publish_message(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TNUMBER || lua_type(L, -3) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } int msg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (msg_ref_id == LUA_REFNIL) - msg_ref_id = 0; - int topic_id = lua_tointeger(L, -1); lua_pop(L, 1); - - void *p = (void *)lua_topointer(L, -1); + struct mq_runtime *rt = (struct mq_runtime *)lua_topointer(L, -1); lua_settop(L, 0); - struct lua_context *new_context = lua_context_new(state); - new_context->lua_context_ref_id = msg_ref_id; + struct lua_context *new_context = lua_context_new_with_ref_id(state, msg_ref_id); - int publish_result = -1; - if (type == MQ_TYPE_PACKET) - publish_result = packet_mq_publish_message((struct packet *)p, topic_id, new_context); - else if (type == MQ_TYPE_SESSION) - publish_result = session_mq_publish_message((struct session *)p, topic_id, new_context); - if (publish_result) + int publish_ret = mq_runtime_publish_message(rt, topic_id, new_context); + if (publish_ret) { - luaL_unref(L, LUA_REGISTRYINDEX, new_context->lua_context_ref_id); - free(new_context); - goto err; + lua_context_free(new_context); + } + lua_pushinteger(L, publish_ret); + return 1; +} + +LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_module_manager_get_thread_id, + struct stellar_module_manager, + stellar_module_manager_get_thread_id) + +LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_module_manager_get_max_thread_num, + struct stellar_module_manager, + stellar_module_manager_get_max_thread_num) + +LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_module_manager_get_mq_runtime, + struct stellar_module_manager, + struct mq_runtime, + stellar_module_manager_get_mq_runtime) + +LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_module_manager_get_mq_schema, + struct stellar_module_manager, + struct mq_schema, + stellar_module_manager_get_mq_schema) + +LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_module_manager_get_logger, + struct stellar_module_manager, + struct logger, + stellar_module_manager_get_logger) + +LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_packet_get_direction, + const struct packet, + packet_get_direction) + +LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_packet_get_payload, + const struct packet, + const char, + packet_get_payload) + +LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_packet_get_payload_len, + const struct packet, + packet_get_payload_len) + +int lua_packet_manager_subscribe(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + if (lua_gettop(L) != 4 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -3) != LUA_TNUMBER || lua_type(L, -4) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; } - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - return 1; -} - -/* ***** ***** ***** ***** ***** ***** */ -int lua_packet_mq_create_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_create_topic(state, MQ_TYPE_PACKET); -} - -int lua_packet_mq_get_topic_id(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_get_topic_id(state, MQ_TYPE_PACKET); -} - -int lua_packet_mq_update_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_update_topic(state, MQ_TYPE_PACKET); -} - -int lua_packet_mq_destory_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_destory_topic(state, MQ_TYPE_PACKET); -} - -int lua_packet_mq_subscribe_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_subscribe_topic(state, MQ_TYPE_PACKET); -} - -int lua_packet_mq_publish_message(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_publish_message(state, MQ_TYPE_PACKET); -} - -/* ***** ***** ***** ***** ***** ***** */ -int lua_session_mq_create_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_create_topic(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_get_topic_id(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_get_topic_id(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_update_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_update_topic(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_destory_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_destory_topic(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_subscribe_topic(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_subscribe_topic(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_publish_message(struct lua_state *state) -{ - return lua_plugin_manage_msg_mq_publish_message(state, MQ_TYPE_SESSION); -} - -int lua_session_mq_ignore_message(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 3) - goto err; - - int plugin_id = lua_tointeger(L, -1); + int on_packet_stage_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_packet_stage_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int stage = lua_tointeger(L, -1); lua_pop(L, 1); - - int topic_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - struct session *sess = (struct session *)lua_topointer(L, -1); + struct packet_manager *pkt_mgr = (struct packet_manager *)lua_topointer(L, -1); lua_settop(L, 0); - if (session_mq_ignore_message(sess, topic_id, plugin_id)) - goto err; - - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - return 1; -} - -int lua_session_mq_unignore_message(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 4) - goto err; - - int plugin_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - int topic_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - struct session *sess = (struct session *)lua_topointer(L, -1); - lua_settop(L, 0); - - if (session_mq_unignore_message(sess, topic_id, plugin_id)) - goto err; - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - - return 1; -} - -int lua_session_mq_topic_is_active(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 2) - goto err; - - int topic_id = lua_tointeger(L, -1); - lua_pop(L, 1); - - struct session *sess = (struct session *)lua_topointer(L, -1); - lua_settop(L, 0); - - /* 1 means active */ - if (session_mq_topic_is_active(sess, topic_id) != 1) - goto err; - lua_pushboolean(L, 1); - return 1; -err: - lua_settop(L, 0); - lua_pushboolean(L, 0); - return 1; -} - -static const char lua_base64_encode_table[] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', - 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '+', '/'}; - -static int lua_base64_encode(const char *indata, int inlen, char *outdata, int *outlen) -{ - if (indata == NULL || inlen <= 0) + struct lua_fn_arg_pair *new_on_packet_arg = CALLOC(struct lua_fn_arg_pair, 1); + new_on_packet_arg->lua_arg_ref_id = on_packet_stage_arg_ref_id; + new_on_packet_arg->lua_fn_ref_id = on_packet_stage_fn_ref_id; + int subscribe_ret = packet_manager_subscribe(pkt_mgr, (enum packet_stage)stage, lua_manager_packet_on_stage_callback, new_on_packet_arg); + if (subscribe_ret) { - return -1; + if (on_packet_stage_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_packet_stage_arg_ref_id); + if (on_packet_stage_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_packet_stage_fn_ref_id); + if (new_on_packet_arg) + FREE(new_on_packet_arg); } - int i, j; - unsigned char num = inlen % 3; - if (outdata != NULL) + else { - // 编码,3个字节一组,若数据总长度不是3的倍数,则跳过最后的 num 个字节数据 - for (i = 0, j = 0; i < inlen - num; i += 3, j += 4) + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_on_packet_arg->lua_mod_mgr = lua_mod_mgr; + LL_APPEND(lua_mod_mgr->on_packet_stage_list, new_on_packet_arg); + } + + lua_pushinteger(L, subscribe_ret); + return 1; +} + +LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_session_get0_current_packet, + const struct session, + const struct packet, + session_get0_current_packet) + +enum sess_mgr_sub_type +{ + sub_type_begin = 0, + sub_type_tcp, + sub_type_udp, + sub_type_control_pkt, + sub_type_end +}; + +static int lua_session_manager_subscribe(struct lua_state *state, enum sess_mgr_sub_type type) +{ + lua_State *L = (lua_State *)state; + if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -3) != LUA_TLIGHTUSERDATA) + { + lua_settop(L, 0); + return 0; + } + + int on_session_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_session_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + struct session_manager *sess_mgr = (struct session_manager *)lua_topointer(L, -1); + lua_settop(L, 0); + + struct lua_fn_arg_pair *new_on_sess_arg = CALLOC(struct lua_fn_arg_pair, 1); + new_on_sess_arg->lua_arg_ref_id = on_session_arg_ref_id; + new_on_sess_arg->lua_fn_ref_id = on_session_fn_ref_id; + int subscribe_ret = -1; + switch (type) + { + case sub_type_tcp: + subscribe_ret = session_manager_subscribe_tcp(sess_mgr, lua_manager_session_callback, new_on_sess_arg); + break; + case sub_type_udp: + subscribe_ret = session_manager_subscribe_udp(sess_mgr, lua_manager_session_callback, new_on_sess_arg); + break; + case sub_type_control_pkt: + subscribe_ret = session_manager_subscribe_control_packet(sess_mgr, lua_manager_session_callback, new_on_sess_arg); + break; + default: + break; + } + if (subscribe_ret) + { + if (on_session_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_session_arg_ref_id); + if (on_session_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_session_fn_ref_id); + if (new_on_sess_arg) + FREE(new_on_sess_arg); + } + else + { + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_on_sess_arg->lua_mod_mgr = lua_mod_mgr; + switch (type) { - outdata[j] = lua_base64_encode_table[(unsigned char)indata[i] >> 2]; - outdata[j + 1] = lua_base64_encode_table[(((unsigned char)indata[i] & 0x03) << 4) | ((unsigned char)indata[i + 1] >> 4)]; - outdata[j + 2] = lua_base64_encode_table[(((unsigned char)indata[i + 1] & 0x0f) << 2) | ((unsigned char)indata[i + 2] >> 6)]; - outdata[j + 3] = lua_base64_encode_table[(unsigned char)indata[i + 2] & 0x3f]; + case sub_type_tcp: + LL_APPEND(lua_mod_mgr->on_session_tcp_list, new_on_sess_arg); + break; + case sub_type_udp: + LL_APPEND(lua_mod_mgr->on_session_udp_list, new_on_sess_arg); + break; + case sub_type_control_pkt: + LL_APPEND(lua_mod_mgr->on_session_control_packet_list, new_on_sess_arg); + break; + default: + break; } - // 继续处理最后的 num 个字节的数据 - if (num == 1) - { // 余数为1,需补齐两个字节'=' - outdata[j] = lua_base64_encode_table[(unsigned char)indata[inlen - 1] >> 2]; - outdata[j + 1] = lua_base64_encode_table[((unsigned char)indata[inlen - 1] & 0x03) << 4]; - outdata[j + 2] = '='; - outdata[j + 3] = '='; - } - else if (num == 2) - { // 余数为2,需补齐一个字节'=' - outdata[j] = lua_base64_encode_table[(unsigned char)indata[inlen - 2] >> 2]; - outdata[j + 1] = lua_base64_encode_table[(((unsigned char)indata[inlen - 2] & 0x03) << 4) | ((unsigned char)indata[inlen - 1] >> 4)]; - outdata[j + 2] = lua_base64_encode_table[((unsigned char)indata[inlen - 1] & 0x0f) << 2]; - outdata[j + 3] = '='; - } - } - if (outlen != NULL) - { - *outlen = (inlen + (num == 0 ? 0 : 3 - num)) * 4 / 3; } - return 0; + lua_pushinteger(L, subscribe_ret); + return 1; } -int lua_session_get0_current_payload(struct lua_state *state) +int lua_session_manager_subscribe_tcp(struct lua_state *state) +{ + return lua_session_manager_subscribe(state, sub_type_tcp); +} + +int lua_session_manager_subscribe_udp(struct lua_state *state) +{ + return lua_session_manager_subscribe(state, sub_type_udp); +} + +int lua_session_manager_subscribe_control_packet(struct lua_state *state) +{ + return lua_session_manager_subscribe(state, sub_type_control_pkt); +} + +int lua_session_manager_subscribe_tcp_stream(struct lua_state *state) { lua_State *L = (lua_State *)state; - if (lua_gettop(L) != 1) - goto err; - - struct session *sess = (struct session *)lua_topointer(L, -1); - lua_settop(L, 0); - - size_t payload_len = 0; - const char *payload = session_get0_current_payload(sess, &payload_len); - -#if 0 - lua_pushlightuserdata(L, (void *)payload); - lua_pushinteger(L, (lua_Integer)payload_len); - return 2; -err: - lua_settop(L, 0); - lua_pushlightuserdata(L, NULL); - lua_pushboolean(L, 0); - return 2; -#else - char *payload_base64 = (char *)calloc(2, payload_len); - int payload_base64_len = 0; - if (!lua_base64_encode(payload, payload_len, payload_base64, &payload_base64_len)) + if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -4) != LUA_TLIGHTUSERDATA) { - lua_pushstring(L, payload_base64); - lua_pushinteger(L, (lua_Integer)payload_len); - if (payload_base64) - free(payload_base64); - return 2; + lua_settop(L, 0); + return 0; } - if (payload_base64) - free(payload_base64); -err: + + int on_tcp_stream_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + int on_tcp_stream_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + struct session_manager *sess_mgr = (struct session_manager *)lua_topointer(L, -1); lua_settop(L, 0); - lua_pushstring(L, NULL); - lua_pushboolean(L, 0); - return 2; -#endif -} \ No newline at end of file + + struct lua_fn_arg_pair *new_on_tcp_stream_arg = CALLOC(struct lua_fn_arg_pair, 1); + new_on_tcp_stream_arg->lua_arg_ref_id = on_tcp_stream_arg_ref_id; + new_on_tcp_stream_arg->lua_fn_ref_id = on_tcp_stream_fn_ref_id; + int subscribe_ret = session_manager_subscribe_tcp_stream(sess_mgr, lua_manager_tcp_stream_callback, new_on_tcp_stream_arg); + if (subscribe_ret) + { + if (on_tcp_stream_arg_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_tcp_stream_arg_ref_id); + if (on_tcp_stream_fn_ref_id + 1) + luaL_unref(L, LUA_REGISTRYINDEX, on_tcp_stream_fn_ref_id); + if (new_on_tcp_stream_arg) + FREE(new_on_tcp_stream_arg); + } + else + { + struct lua_module_manager *lua_mod_mgr = lua_state_get_lua_module_manager(state); + new_on_tcp_stream_arg->lua_mod_mgr = lua_mod_mgr; + LL_APPEND(lua_mod_mgr->on_tcp_stream_list, new_on_tcp_stream_arg); + } + + lua_pushinteger(L, subscribe_ret); + return 1; +} diff --git a/src/lua_binding_function.h b/src/lua_binding_function.h index ba515cc..ffd039e 100644 --- a/src/lua_binding_function.h +++ b/src/lua_binding_function.h @@ -1,53 +1,32 @@ -#include "stellar/stellar.h" -#include "stellar/packet_mq.h" -#include "stellar/session.h" -#include "stellar/session_mq.h" +#ifndef LUA_MODULE_MANAGE_BINDING_FUNCTION_H +#define LUA_MODULE_MANAGE_BINDING_FUNCTION_H -#include "lua_plugin_manage_internal.h" +#include "lua_module_manage_internal.h" -/* ***** ***** ***** ***** ***** ***** */ -/* 需要注册至lua中供lua调用的所有函数原型 */ -/* 通用函数 */ -int lua_get_worker_thread_num(struct lua_state *state); -int lua_get_current_thread_id(struct lua_state *state); -int lua_get_stellar_pointer(struct lua_state *state); -// int lua_get_plugin_manage_pointer(struct lua_state *state); +int lua_mq_schema_get_topic_id(struct lua_state *state); +int lua_mq_schema_create_topic(struct lua_state *state); +int lua_mq_schema_update_topic(struct lua_state *state); +int lua_mq_shcema_destory_topic(struct lua_state *state); +int lua_mq_schema_subscribe(struct lua_state *state); +int lua_mq_runtime_publish_message(struct lua_state *state); -/* 注册函数 */ -int lua_session_plugin_regist(struct lua_state *state); -int lua_packet_plugin_regist(struct lua_state *state); +int lua_module_manager_get_thread_id(struct lua_state *state); +int lua_module_manager_get_max_thread_num(struct lua_state *state); +int lua_module_manager_get_mq_runtime(struct lua_state *state); +int lua_module_manager_get_mq_schema(struct lua_state *state); +int lua_module_manager_get_logger(struct lua_state *state); -/* struct session结构相关的函数 */ -int lua_session_get_type(struct lua_state *state); +int lua_packet_get_direction(struct lua_state *state); +int lua_packet_get_payload(struct lua_state *state); +int lua_packet_get_payload_len(struct lua_state *state); -/* packet message mq相关的函数 */ -int lua_packet_mq_create_topic(struct lua_state *state); -int lua_packet_mq_get_topic_id(struct lua_state *state); -int lua_packet_mq_update_topic(struct lua_state *state); -int lua_packet_mq_destory_topic(struct lua_state *state); -int lua_packet_mq_subscribe_topic(struct lua_state *state); -int lua_packet_mq_publish_message(struct lua_state *state); +int lua_packet_manager_subscribe(struct lua_state *state); -/* session message mq相关的函数 */ -int lua_session_mq_create_topic(struct lua_state *state); -int lua_session_mq_get_topic_id(struct lua_state *state); -int lua_session_mq_update_topic(struct lua_state *state); -int lua_session_mq_destory_topic(struct lua_state *state); -int lua_session_mq_subscribe_topic(struct lua_state *state); -int lua_session_mq_publish_message(struct lua_state *state); -int lua_session_mq_topic_is_active(struct lua_state *state); -int lua_session_mq_ignore_message(struct lua_state *state); -int lua_session_mq_unignore_message(struct lua_state *state); +int lua_session_get0_current_packet(struct lua_state *state); -/* session相关其他函数 */ -int lua_session_get0_current_payload(struct lua_state *state); +int lua_session_manager_subscribe_tcp(struct lua_state *state); +int lua_session_manager_subscribe_udp(struct lua_state *state); +int lua_session_manager_subscribe_control_packet(struct lua_state *state); +int lua_session_manager_subscribe_tcp_stream(struct lua_state *state); -/* ***** ***** ***** ***** ***** ***** */ -/* 此部分为注册至C中的lua通用函数, 实现在lua_plugin_cfunc.c中 */ -void *lpm_ctx_new_func(struct session *sess, void *plugin_env); -void lpm_ctx_free_func(struct session *sess, void *sess_ctx, void *plugin_env); -void lpm_session_message_free_func(struct session *sess, void *msg, void *msg_free_arg); -void lpm_on_session_msg_func(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_env); -void lpm_on_packet_func(struct packet *pkt, unsigned char ip_protocol, void *plugin_env); -void lpm_packet_message_free_func(struct packet *pkt, void *msg, void *msg_free_arg); -void lpm_on_packet_msg_func(struct packet *pkt, int topic_id, const void *msg, void *plugin_env); \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/lua_module_manage.c b/src/lua_module_manage.c new file mode 100644 index 0000000..e0a2d0d --- /dev/null +++ b/src/lua_module_manage.c @@ -0,0 +1,137 @@ +#include "lua_module_manage_internal.h" +#include "lua_binding_function.h" + +#include "stellar/utils.h" + +#include +#include +#include + +#define MQ_SCHEMA_SPACE_NAME "mq_schema" +#define MQ_RUNTIME_SPACE_NAME "mq_runtime" +#define MODULE_MANAGER_SPACE_NAME "module_manager" +#define PACKET_SPACE_NAME "packet" +#define PACKET_MANAGER_SPACE_NAME "packet_manager" +#define SESSION_SPACE_NAME "session" +#define SESSION_MANAGER_SPACE_NAME "session_manager" + +struct lua_bind_func_spec lua_bind_function[] = { + {lua_mq_schema_get_topic_id, MQ_SCHEMA_SPACE_NAME, "get_topic_id"}, + {lua_mq_schema_create_topic, MQ_SCHEMA_SPACE_NAME, "create_topic"}, + {lua_mq_schema_update_topic, MQ_SCHEMA_SPACE_NAME, "update_topic"}, + {lua_mq_shcema_destory_topic, MQ_SCHEMA_SPACE_NAME, "destory_topic"}, + {lua_mq_schema_subscribe, MQ_SCHEMA_SPACE_NAME, "subcribe"}, + {lua_mq_runtime_publish_message, MQ_RUNTIME_SPACE_NAME, "publish_message"}, + + {lua_module_manager_get_thread_id, MODULE_MANAGER_SPACE_NAME, "get_thread_id"}, + {lua_module_manager_get_max_thread_num, MODULE_MANAGER_SPACE_NAME, "get_max_thread_num"}, + {lua_module_manager_get_mq_runtime, MODULE_MANAGER_SPACE_NAME, "get_mq_runtime"}, + {lua_module_manager_get_mq_schema, MODULE_MANAGER_SPACE_NAME, "get_mq_schema"}, + {lua_module_manager_get_logger, MODULE_MANAGER_SPACE_NAME, "get_logger"}, + + {lua_packet_get_direction, PACKET_SPACE_NAME, "get_direction"}, + {lua_packet_get_payload, PACKET_SPACE_NAME, "get_payload"}, + {lua_packet_get_payload_len, PACKET_SPACE_NAME, "get_payload_len"}, + + {lua_packet_manager_subscribe, PACKET_MANAGER_SPACE_NAME, "subscribe"}, + + {lua_session_get0_current_packet, SESSION_SPACE_NAME, "get0_current_payload"}, + + {lua_session_manager_subscribe_tcp, SESSION_MANAGER_SPACE_NAME, "subscribe_tcp"}, + {lua_session_manager_subscribe_udp, SESSION_MANAGER_SPACE_NAME, "subscribe_udp"}, + {lua_session_manager_subscribe_control_packet, SESSION_MANAGER_SPACE_NAME, "subscribe_control_packet"}, + {lua_session_manager_subscribe_tcp_stream, SESSION_MANAGER_SPACE_NAME, "subscribe_tcp_stream"}, + {NULL, NULL, NULL}, +}; + +#define ENUM_PACKET_STAGE_SPACE_NAME "packet_stage" + +struct lua_bind_data_spec lua_bind_data[] = { + {DATATYPE_INT, "0", ENUM_PACKET_STAGE_SPACE_NAME, "prerouting"}, + {DATATYPE_INT, "1", ENUM_PACKET_STAGE_SPACE_NAME, "input"}, + {DATATYPE_INT, "2", ENUM_PACKET_STAGE_SPACE_NAME, "forward"}, + {DATATYPE_INT, "3", ENUM_PACKET_STAGE_SPACE_NAME, "output"}, + {DATATYPE_INT, "4", ENUM_PACKET_STAGE_SPACE_NAME, "postrouting"}, + {DATATYPE_END, NULL, NULL, NULL}, +}; + +static void lua_module_manager_free(struct lua_module_manager *lua_mod_mgr) +{ + if (!lua_mod_mgr) + return; + for (size_t script_index = 0; script_index < lua_mod_mgr->load_script_num; ++script_index) + { + lua_chunk_execute(lua_mod_mgr->state_array[0], lua_mod_mgr->load_script_array[script_index].lua_unload_fn_ref_id, NULL, 0, NULL, 0, NULL, 0); + } + for (size_t state_index = 0; state_index < lua_mod_mgr->state_num; ++state_index) + { + lua_state_free(lua_mod_mgr->state_array[state_index]); + } + FREE(lua_mod_mgr); + return; +} + +struct stellar_module *lua_module_manager_on_init(struct stellar_module_manager *mod_mgr) +{ + struct stellar_module *new_mod = NULL; + struct lua_module_manager *new_lua_manage = CALLOC(struct lua_module_manager, 1); + memset(new_lua_manage, 0, sizeof(struct lua_module_manager)); + new_lua_manage->mod_mgr = mod_mgr; + + int thread_count = stellar_module_manager_get_max_thread_num(mod_mgr); + if (thread_count <= 0) + goto init_lua_module_finish; + new_lua_manage->state_num = (size_t)thread_count; + new_lua_manage->state_array = CALLOC(struct lua_state *, thread_count); + memset(new_lua_manage->state_array, 0, thread_count * sizeof(struct lua_state *)); + for (size_t thread_index = 0; thread_index < new_lua_manage->state_num; ++thread_index) + { + new_lua_manage->state_array[thread_index] = lua_state_new(new_lua_manage); + lua_cbinding_function(new_lua_manage->state_array[thread_index], lua_bind_function, (sizeof(lua_bind_function) / sizeof(struct lua_bind_func_spec))); + lua_cbinding_data(new_lua_manage->state_array[thread_index], lua_bind_data, (sizeof(lua_bind_data) / sizeof(struct lua_bind_data_spec))); + } + + struct lua_module_spec *module_spec = lua_module_config_file_load(LUA_MODULE_MANAGE_CONF_PATH, &new_lua_manage->load_script_num); + if (new_lua_manage->load_script_num && module_spec) + { + new_lua_manage->load_script_array = CALLOC(struct lua_load_script, new_lua_manage->load_script_num); + for (size_t script_index = 0; script_index < new_lua_manage->load_script_num; ++script_index) + { + if (lua_load_script_load_single_specific(&new_lua_manage->load_script_array[script_index], new_lua_manage->state_array[0], &module_spec[script_index])) + { + lua_module_spec_free(module_spec, new_lua_manage->load_script_num); + goto err; + } + } + } + else + { + goto init_lua_module_finish; + } + lua_module_spec_free(module_spec, new_lua_manage->load_script_num); + for (size_t script_index = 0; script_index < new_lua_manage->load_script_num; ++script_index) + { + lua_chunk_execute(new_lua_manage->state_array[0], new_lua_manage->load_script_array[script_index].lua_load_fn_ref_id, NULL, 0, NULL, 0, NULL, 0); + } + + for (size_t thread_index = 1; thread_index < new_lua_manage->state_num; ++thread_index) + { + lua_state_copy_ref_value(new_lua_manage->state_array[thread_index], new_lua_manage->state_array[0]); + } + +init_lua_module_finish: + new_mod = stellar_module_new(LUA_MODULE_MANAGE_MODULE_NAME, (void *)new_lua_manage); + return new_mod; +err: + if (new_lua_manage) + lua_module_manager_free(new_lua_manage); + return NULL; +} + +void lua_module_manager_on_exit(struct stellar_module_manager *mod_mgr __unused, struct stellar_module *mod) +{ + struct lua_module_manager *lua_mod_mgr = (struct lua_module_manager *)stellar_module_get_ctx(mod); + lua_module_manager_free(lua_mod_mgr); + stellar_module_free(mod); + return; +} \ No newline at end of file diff --git a/src/lua_module_manage_internal.c b/src/lua_module_manage_internal.c new file mode 100644 index 0000000..bc5520d --- /dev/null +++ b/src/lua_module_manage_internal.c @@ -0,0 +1,862 @@ +#include "lua_module_manage_internal.h" + +#include "stellar/utils.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* ***** ***** ***** ***** ***** ***** */ +/* lua state */ +/* ***** ***** ***** ***** ***** ***** */ +struct lua_state +{ + lua_State *state; +}; + +#define LUA_GLOBAL_INFO_REF_ID (LUA_RIDX_LAST + 2) +#define LUA_GLOBAL_INFO_MANAGE_POINTER "__global_lua_module_manage" +// #define LUA_GLOBAL_FUNCTION_REF_ID (LUA_RIDX_LAST + 3) +// #define LUA_GLOBAL_CONTEXT_REF_ID (LUA_RIDX_LAST + 4) + +struct lua_state *lua_state_new(struct lua_module_manager *lua_mod_mgr) +{ + lua_State *new_L = luaL_newstate(); + if (!new_L) + return NULL; + luaL_openlibs(new_L); + + lua_newtable(new_L); + lua_pushlightuserdata(new_L, (void *)lua_mod_mgr); + lua_setfield(new_L, -2, LUA_GLOBAL_INFO_MANAGE_POINTER); + int global_ref = luaL_ref(new_L, LUA_REGISTRYINDEX); + lua_settop(new_L, 0); + assert(global_ref == LUA_GLOBAL_INFO_REF_ID); + + return (struct lua_state *)new_L; +} + +void lua_state_free(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + lua_close(L); + return; +} + +struct lua_module_manager *lua_state_get_lua_module_manager(struct lua_state *state) +{ + lua_State *L = (lua_State *)state; + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_GLOBAL_INFO_REF_ID); + lua_getfield(L, -1, LUA_GLOBAL_INFO_MANAGE_POINTER); + struct lua_module_manager *lua_mod_mgr = (struct lua_module_manager *)lua_topointer(L, -1); + lua_settop(L, 0); + return lua_mod_mgr; +} + +int lua_state_copy_ref_value(struct lua_state *to, struct lua_state *from) +{ + if (!to || !from) + return PARAM_ERR; + lua_State *from_L = (lua_State *)from; + lua_State *to_L = (lua_State *)to; + + lua_newtable(from_L); + int lua_ref_max_id = luaL_ref(from_L, LUA_REGISTRYINDEX); + int data_ret = 0; + for (int ref_index = (LUA_GLOBAL_INFO_REF_ID + 1); ref_index < lua_ref_max_id; ++ref_index) + { + struct lua_cdata *trans_data = lua_cdata_new(); + lua_settop(from_L, 0); + lua_rawgeti(from_L, LUA_REGISTRYINDEX, ref_index); + data_ret = lua_cdata_pop_stack(from, trans_data); + if (data_ret) + { + lua_cdata_free(trans_data); + return data_ret; + } + data_ret = lua_cdata_push_stack(to, trans_data); + if (data_ret) + { + lua_cdata_free(trans_data); + return data_ret; + } + int ref_id = luaL_ref(to_L, LUA_REGISTRYINDEX); + lua_cdata_free(trans_data); + if (ref_id != ref_index) + { + return STATE_COPY_REF_VALUE_ERR; + } + } + luaL_unref(from_L, LUA_REGISTRYINDEX, lua_ref_max_id); + return SUCCESS; +} + +/* ***** ***** ***** ***** ***** ***** */ +/* read lua module config */ +/* ***** ***** ***** ***** ***** ***** */ +struct lua_module_spec *lua_module_config_file_load(const char *config_file_name, size_t *spec_num) +{ + *spec_num = 0; + if (access(config_file_name, F_OK)) + return NULL; + FILE *fp = fopen(config_file_name, "r"); + if (!fp) + return NULL; + char errbuff[256] = {0}; + toml_table_t *toml_table = toml_parse_file(fp, errbuff, sizeof(errbuff)); + if (fp) + fclose(fp); + if (!toml_table) + return NULL; + toml_array_t *module_array = toml_array_in(toml_table, "module"); + if (!module_array) + { + toml_free(toml_table); + return NULL; + } + + int specific_nelem = toml_array_nelem(module_array); + struct lua_module_spec *new_spec = CALLOC(struct lua_module_spec, specific_nelem); + memset(new_spec, 0, (sizeof(struct lua_module_spec) * specific_nelem)); + + for (int i = 0; i < specific_nelem; ++i) + { + toml_table_t *plugin = toml_table_at(module_array, i); + const char *raw_filepath = toml_raw_in(plugin, "path"); + const char *raw_load_func_name = toml_raw_in(plugin, "init"); + const char *raw_unload_func_name = toml_raw_in(plugin, "exit"); + + /* TODO:是不是需要进行一下配置检查 */ + new_spec[i].spec_file_path = strdup(raw_filepath); + new_spec[i].spec_load_func_name = strdup(raw_load_func_name); + new_spec[i].spec_unload_func_name = strdup(raw_unload_func_name); + } + toml_free(toml_table); + *spec_num = specific_nelem; + return new_spec; +} + +void lua_module_spec_free(struct lua_module_spec spec[], size_t spec_num) +{ + if (!spec) + return; + for (size_t spec_index = 0; spec_index < spec_num; ++spec_index) + { + if (spec[spec_index].spec_file_path) + FREE(spec[spec_index].spec_file_path); + if (spec[spec_index].spec_load_func_name) + FREE(spec[spec_index].spec_load_func_name); + if (spec[spec_index].spec_unload_func_name) + FREE(spec[spec_index].spec_unload_func_name); + } + FREE(spec); + return; +} + +/* ***** ***** ***** ***** ***** ***** */ +/* binding function or data to state */ +/* ***** ***** ***** ***** ***** ***** */ +static int lua_cbinding_single_function(struct lua_state *state, struct lua_bind_func_spec *func_spec) +{ + lua_State *L = (lua_State *)state; + if (func_spec->space_name) + { + lua_getglobal(L, func_spec->space_name); + if (lua_type(L, -1) == LUA_TNIL) + { + lua_pop(L, 1); + lua_newtable(L); + } + else + { + if (lua_type(L, -1) != LUA_TTABLE) + { + lua_settop(L, 0); + return CFUNC_BIND_NAMESPACE_CONFLICT; + } + lua_getfield(L, -1, func_spec->func_name); + if (lua_type(L, -1) != LUA_TNIL) + { + lua_settop(L, 0); + return CFUNC_BIND_NAME_CONFLICT; + } + lua_pop(L, 1); + } + lua_pushcfunction(L, (lua_CFunction)func_spec->func); + lua_setfield(L, -2, func_spec->func_name); + lua_setglobal(L, func_spec->space_name); + } + else + { + lua_getglobal(L, func_spec->func_name); + if (lua_type(L, -1) != LUA_TNIL) + { + lua_settop(L, 0); + return CFUNC_BIND_NAME_CONFLICT; + } + lua_pop(L, 1); + lua_pushcfunction(L, (lua_CFunction)func_spec->func); + lua_setglobal(L, func_spec->func_name); + } + lua_settop(L, 0); + return SUCCESS; +} + +static int lua_cbinding_single_data(struct lua_state *state, struct lua_bind_data_spec *data_spec) +{ + lua_State *L = (lua_State *)state; + if (data_spec->space_name) + { + lua_getglobal(L, data_spec->space_name); + if (lua_type(L, -1) == LUA_TNIL) + { + lua_pop(L, 1); + lua_newtable(L); + } + else + { + if (lua_type(L, -1) != LUA_TTABLE) + { + lua_settop(L, 0); + return CDATA_BIND_NAMESPACE_CONFLICT; + } + lua_getfield(L, -1, data_spec->data_name); + if (lua_type(L, -1) != LUA_TNIL) + { + lua_settop(L, 0); + return CDATA_BIND_NAME_CONFLICT; + } + lua_pop(L, 1); + } + + switch (data_spec->data_type) + { + case DATATYPE_BOOL: + if (strstr(data_spec->data_value, "true") || strstr(data_spec->data_value, "TRUE")) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + break; + case DATATYPE_INT: + lua_pushinteger(L, atoi(data_spec->data_value)); + break; + case DATATYPE_NUM: + lua_pushnumber(L, (lua_Number)atof(data_spec->data_value)); + break; + case DATATYPE_STRING: + lua_pushlstring(L, (const char *)data_spec->data_value, strlen(data_spec->data_value)); + break; + default: + lua_settop(L, 0); + return CDATA_BIND_TYPE_ERR; + } + lua_setfield(L, -2, data_spec->data_name); + lua_setglobal(L, data_spec->space_name); + } + else + { + lua_getglobal(L, data_spec->data_name); + if (lua_type(L, -1) != LUA_TNIL) + { + lua_settop(L, 0); + return CDATA_BIND_NAME_CONFLICT; + } + lua_pop(L, 1); + + switch (data_spec->data_type) + { + case DATATYPE_BOOL: + if (strstr(data_spec->data_value, "true") || strstr(data_spec->data_value, "TRUE")) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + break; + case DATATYPE_INT: + lua_pushinteger(L, atoi(data_spec->data_value)); + break; + case DATATYPE_NUM: + lua_pushnumber(L, (lua_Number)atof(data_spec->data_value)); + break; + case DATATYPE_STRING: + lua_pushlstring(L, (const char *)data_spec->data_value, strlen(data_spec->data_value)); + break; + default: + lua_settop(L, 0); + return CDATA_BIND_TYPE_ERR; + } + lua_setglobal(L, data_spec->data_name); + } + lua_settop(L, 0); + return SUCCESS; +} + +int lua_cbinding_function(struct lua_state *state, struct lua_bind_func_spec bind_function[], size_t bind_func_num) +{ + if (!state || !bind_function) + return PARAM_ERR; + for (size_t index = 0; index < bind_func_num; ++index) + { + if (bind_function[index].func && bind_function[index].func_name) + { + int bind_ret = lua_cbinding_single_function(state, &bind_function[index]); + if (bind_ret) + return bind_ret; + } + else + break; + } + return SUCCESS; +} + +int lua_cbinding_data(struct lua_state *state, struct lua_bind_data_spec bind_data[], size_t bind_data_num) +{ + if (!state || !bind_data) + return PARAM_ERR; + for (size_t index = 0; index < bind_data_num; ++index) + { + if (bind_data[index].data_value && bind_data[index].data_name) + { + int bind_ret = lua_cbinding_single_data(state, &bind_data[index]); + if (bind_ret) + return bind_ret; + } + else + break; + } + return SUCCESS; +} + +/* ***** ***** ***** ***** ***** ***** */ +/* context */ +/* ***** ***** ***** ***** ***** ***** */ +const char *context_magic_code = "ctx_code"; +struct lua_context +{ + const char *magic_code; + struct lua_state *state; + int lua_context_ref_id; +}; + +struct lua_context *lua_context_new(struct lua_state *state) +{ + if (!state) + return NULL; + lua_State *L = (lua_State *)state; + + lua_newtable(L); + int ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + struct lua_context *new_context = lua_context_new_with_ref_id(state, ref_id); + if (!new_context) + luaL_unref(L, LUA_REGISTRYINDEX, ref_id); + return new_context; +} + +struct lua_context *lua_context_new_with_ref_id(struct lua_state *state, int ref_id) +{ + if (!state) + return NULL; + struct lua_context *new_context = CALLOC(struct lua_context, 1); + new_context->magic_code = context_magic_code; + new_context->state = state; + new_context->lua_context_ref_id = ref_id; + return new_context; +} + +void lua_context_free(struct lua_context *context) +{ + if (!context) + return; + luaL_unref((lua_State *)context->state, LUA_REGISTRYINDEX, context->lua_context_ref_id); + FREE(context); + return; +} + +void lua_context_push_stack(struct lua_context *context) +{ + if (context && context->lua_context_ref_id) + lua_rawgeti((lua_State *)context->state, LUA_REGISTRYINDEX, context->lua_context_ref_id); + return; +} + +int lua_context_check_if_context(void *context) +{ + struct lua_context *check = (struct lua_context *)context; + if (check && check->magic_code == context_magic_code) + return TRUE; + return FALSE; +} + +/* ***** ***** ***** ***** ***** ***** */ +/* trans data between C and Lua */ +/* ***** ***** ***** ***** ***** ***** */ +struct lua_cnode +{ + char *node_string_key; + int node_integer_key; + struct lua_cdata *node_data; +}; + +struct lua_ctable +{ + size_t array_size; + size_t node_size; + struct lua_cdata **array_data; + struct lua_cnode **node_data; +}; + +static struct lua_ctable *lua_ctable_new(void); +static void lua_ctable_free(struct lua_ctable *ctable); +static int lua_ctable_push_stack(struct lua_state *state, struct lua_ctable *ctable); +static int lua_ctable_pop_stack(struct lua_state *state, struct lua_ctable *ctable); +static struct lua_cnode *lua_cnode_new(void); +static void lua_cnode_free(struct lua_cnode *cnode); +static int lua_cdata_function_reader(lua_State *state __unused, const void *p, size_t sz, void *ud); +static const char *lua_cdata_function_writer(lua_State *state __unused, void *ud, size_t *sz); + +struct lua_cdata *lua_cdata_new(void) +{ + struct lua_cdata *new_data = CALLOC(struct lua_cdata, 1); + memset(new_data, 0, sizeof(struct lua_cdata)); + return new_data; +} + +static void lua_cdata_inner_data_free(struct lua_cdata *cdata) +{ + cdata->type = 0; + cdata->data_len = 0; + switch (cdata->type) + { + case DATATYPE_STRING: + FREE(cdata->string); + break; + case DATATYPE_LUA_TABLE: + lua_ctable_free(cdata->ctable); + break; + case DATATYPE_BUFF: + FREE(cdata->buff); + break; + case DATATYPE_FUNCTION: + FREE(cdata->function); + break; + default: + break; + } + return; +} + +void lua_cdata_free(struct lua_cdata *cdata) +{ + if (!cdata) + return; + lua_cdata_inner_data_free(cdata); + FREE(cdata); + return; +} + +int lua_cdata_data_set(struct lua_cdata *cdata, enum LUA_DATATYPE type, void *value_p, int value_i) +{ + if (!cdata) + return PARAM_ERR; + lua_cdata_inner_data_free(cdata); + switch (type) + { + case DATATYPE_NIL: + break; + case DATATYPE_BOOL: + cdata->bool = value_i; + break; + case DATATYPE_INT: + cdata->integer = value_i; + break; + case DATATYPE_NUM: + cdata->number = *(double *)value_p; + break; + case DATATYPE_STRING: + cdata->string = CALLOC(char, value_i); + memcpy(cdata->string, value_p, (size_t)value_i); + break; + case DATATYPE_BUFF: + cdata->buff = CALLOC(char, value_i); + memcpy(cdata->buff, value_p, (size_t)value_i); + cdata->data_len = (size_t)value_i; + break; + case DATATYPE_TABLE: + cdata->table = value_i; + break; + case DATATYPE_POINTER: + cdata->pointer = value_p; + break; + case DATATYPE_CONTEXT: + cdata->context = (struct lua_context *)value_p; + break; + default: + return CDATA_SET_VALUE_TYPE_UNSUPPORT; + } + cdata->type = type; + return SUCCESS; +} + +int lua_cdata_push_stack(struct lua_state *state, struct lua_cdata *cdata) +{ + if (!state || !cdata) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + + switch (cdata->type) + { + case DATATYPE_NIL: + lua_pushnil(L); + break; + case DATATYPE_BOOL: + lua_pushboolean(L, cdata->bool); + break; + case DATATYPE_INT: + lua_pushinteger(L, cdata->integer); + break; + case DATATYPE_NUM: + lua_pushnumber(L, cdata->number); + break; + case DATATYPE_STRING: + lua_pushstring(L, cdata->string); + break; + case DATATYPE_BUFF: + lua_pushlstring(L, cdata->buff, cdata->data_len); + break; + case DATATYPE_TABLE: + if (cdata->table) + lua_rawgeti(L, LUA_REGISTRYINDEX, cdata->table); + break; + case DATATYPE_LUA_TABLE: + lua_ctable_push_stack(state, cdata->ctable); + break; + case DATATYPE_POINTER: + lua_pushlightuserdata(L, (void *)cdata->pointer); + break; + case DATATYPE_CONTEXT: + lua_context_push_stack(cdata->context); + break; + case DATATYPE_FUNCTION: + lua_load(L, lua_cdata_function_writer, (void *)cdata, NULL, NULL); + break; + default: + return CDATA_PUSH_STACK_TYPE_UNKNOWN; + } + return SUCCESS; +} + +int lua_cdata_pop_stack(struct lua_state *state, struct lua_cdata *cdata) +{ + if (!state || !cdata) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + + lua_cdata_inner_data_free(cdata); + switch (lua_type(L, -1)) + { + case LUA_TNIL: + cdata->type = DATATYPE_NIL; + break; + case LUA_TBOOLEAN: + cdata->type = DATATYPE_BOOL; + cdata->bool = lua_toboolean(L, -1); + break; + case LUA_TLIGHTUSERDATA: + cdata->type = DATATYPE_POINTER; + cdata->pointer = (void *)lua_topointer(L, -1); + break; + case LUA_TNUMBER: + cdata->type = DATATYPE_NUM; + cdata->number = lua_tonumber(L, -1); + int try_int = (int)cdata->number; + if ((double)try_int == cdata->number) + { + cdata->type = DATATYPE_INT; + cdata->integer = lua_tointeger(L, -1); + } + break; + case LUA_TSTRING: + cdata->type = DATATYPE_STRING; + cdata->string = (char *)strdup(lua_tostring(L, -1)); + break; + case LUA_TTABLE: + cdata->type = DATATYPE_LUA_TABLE; + cdata->ctable = lua_ctable_new(); + lua_ctable_pop_stack(state, cdata->ctable); + break; + case LUA_TFUNCTION: + cdata->type = DATATYPE_FUNCTION; + lua_dump(L, lua_cdata_function_reader, cdata, 0); + break; + case LUA_TUSERDATA: + cdata->type = DATATYPE_POINTER; + cdata->pointer = (void *)lua_topointer(L, -1); + break; + default: + return CDATA_POP_STACK_TYPE_UNSUPPORT; + } + lua_pop(L, 1); + return SUCCESS; +} + +static struct lua_ctable *lua_ctable_new(void) +{ + struct lua_ctable *new_table = CALLOC(struct lua_ctable, 1); + memset(new_table, 0, sizeof(struct lua_ctable)); + return new_table; +} + +static void lua_ctable_free(struct lua_ctable *ctable) +{ + if (!ctable) + return; + for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) + { + lua_cdata_free(ctable->array_data[array_index]); + } + for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) + { + lua_cnode_free(ctable->node_data[node_index]); + } + if (ctable->array_data) + FREE(ctable->array_data); + if (ctable->node_data) + FREE(ctable->node_data); + FREE(ctable); + return; +} + +static int lua_ctable_push_stack(struct lua_state *state, struct lua_ctable *ctable) +{ + if (!state || !ctable) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + lua_newtable(L); + int push_ret = 0; + for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) + { + lua_pushinteger(L, (array_index + 1)); + push_ret = lua_cdata_push_stack(state, ctable->array_data[array_index]); + if (push_ret) + { + lua_settop(L, 0); + return push_ret; + } + lua_settable(L, -3); + } + for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) + { + if (ctable->node_data[node_index]->node_string_key) + lua_pushstring(L, ctable->node_data[node_index]->node_string_key); + else + lua_pushinteger(L, ctable->node_data[node_index]->node_integer_key); + push_ret = lua_cdata_push_stack(state, ctable->node_data[node_index]->node_data); + if (push_ret) + { + lua_settop(L, 0); + return push_ret; + } + lua_settable(L, -3); + } + + return SUCCESS; +} + +static int lua_ctable_pop_stack(struct lua_state *state, struct lua_ctable *ctable) +{ + if (!state || !ctable) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + + /* 获取table长度 */ + ctable->array_size = (size_t)lua_rawlen(L, -1); + lua_pushnil(L); + while (lua_next(L, -2)) + { + ctable->node_size++; + if (lua_type(L, -2) == LUA_TNUMBER) + { + int numkey = lua_tointeger(L, -2); + if (numkey > 0 && numkey <= (int)ctable->array_size) + ctable->node_size--; + } + lua_pop(L, 1); + } + + ctable->array_data = CALLOC(struct lua_cdata *, ctable->array_size); + for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) + { + ctable->array_data[array_index] = lua_cdata_new(); + } + ctable->node_data = CALLOC(struct lua_cnode *, ctable->node_size); + for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) + { + ctable->node_data[node_index] = lua_cnode_new(); + } + + /* 依次获取数据 */ + int key_index = 0; + lua_pushnil(L); + while (lua_next(L, -2)) + { + if (lua_type(L, -2) == LUA_TNUMBER) + { + int numkey = lua_tointeger(L, -2); + if (numkey > 0 && numkey <= (int)ctable->array_size) + lua_cdata_pop_stack(state, ctable->array_data[numkey - 1]); + else + { + lua_cdata_pop_stack(state, ctable->node_data[key_index]->node_data); + ctable->node_data[key_index]->node_integer_key = lua_tointeger(L, -1); + ++key_index; + } + } + else if (lua_type(L, -2) == LUA_TSTRING) + { + lua_cdata_pop_stack(state, ctable->node_data[key_index]->node_data); + ctable->node_data[key_index]->node_string_key = strdup((char *)lua_tostring(L, -1)); + ++key_index; + } + } + + lua_settop(L, 0); + return SUCCESS; +} + +static struct lua_cnode *lua_cnode_new(void) +{ + struct lua_cnode *new_node = CALLOC(struct lua_cnode, 1); + memset(new_node, 0, sizeof(struct lua_cnode)); + new_node->node_data = lua_cdata_new(); + return new_node; +} + +static void lua_cnode_free(struct lua_cnode *cnode) +{ + if (cnode->node_string_key) + FREE(cnode->node_string_key); + if (cnode->node_data) + lua_cdata_free(cnode->node_data); + FREE(cnode); + return; +} + +static int lua_cdata_function_reader(lua_State *state __unused, const void *p, size_t sz, void *ud) +{ + /* TODO: 这个函数在lua中会被大量调用, 频繁的realloc可能会导致内存碎片化, 后续调整一下内存分配机制 */ + struct lua_cdata *data = (struct lua_cdata *)ud; + data->type = DATATYPE_FUNCTION; + if (!data->function) + data->function = (void *)calloc(1, sizeof(sz)); + else + data->function = (void *)realloc(data->function, (data->data_len + sz)); + memcpy((data->function + data->data_len), p, sz); + data->data_len += sz; + return 0; +} + +static const char *lua_cdata_function_writer(lua_State *state __unused, void *ud, size_t *sz) +{ + struct lua_cdata *data = (struct lua_cdata *)ud; + *sz = data->data_len; + return (const char *)data->function; +} + +/* ***** ***** ***** ***** ***** ***** */ +/* execute one chunk */ +/* ***** ***** ***** ***** ***** ***** */ +int lua_chunk_execute( + struct lua_state *state, + int fn_ref_id, + struct lua_cdata param[], + size_t param_num, + struct lua_cdata returnvalue[], + size_t r_num, + char *errlog, + size_t err_len) +{ + if (!state || fn_ref_id <= 0 || (param_num && !param) || (r_num && !returnvalue)) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + + lua_rawgeti(L, LUA_REGISTRYINDEX, fn_ref_id); + if (lua_type(L, -1) != LUA_TFUNCTION) + { + lua_settop(L, 0); + return CHUNK_EXECUTE_TYPE_NOT_FUNCTION; + } + + int pushret = 0; + for (unsigned param_index = 0; param_index < param_num; ++param_index) + { + if ((pushret = lua_cdata_push_stack(state, ¶m[param_index]))) + { + lua_settop(L, 0); + return pushret; + } + } + + if (lua_pcall(L, param_num, LUA_MULTRET, 0)) + { + if (errlog) + snprintf(errlog, (err_len - 1), "run script[%d] err %s\n", fn_ref_id, lua_tostring(L, -1)); + lua_settop(L, 0); + return CHUNK_EXECUTE_RUN_CODE_ERR; + } + + if (r_num > 0) + { + int count = lua_gettop(L); + /* 如果接收返回值数量不够, 只保留前r_num个返回值 */ + if (count > (int)r_num) + { + lua_pop(L, (count - (int)r_num)); + count = (int)r_num; + } + int pop_ret = 0; + for (int i = (count - 1); i >= 0; --i) + { + if ((pop_ret = lua_cdata_pop_stack(state, &(returnvalue[i])))) + { + lua_settop(L, 0); + return pop_ret; + } + } + } + + lua_settop(L, 0); + return SUCCESS; +} + +int lua_load_script_load_single_specific(struct lua_load_script *script, struct lua_state *state, struct lua_module_spec *module_spec) +{ + if (!state || !module_spec || !script) + return PARAM_ERR; + lua_State *L = (lua_State *)state; + if (luaL_loadfile(L, module_spec->spec_file_path) || lua_pcall(L, 0, 0, 0)) + { + lua_settop(L, 0); + return SCRIPT_LOAD_FILE_ERR; + } + + lua_getglobal(L, module_spec->spec_load_func_name); + lua_getglobal(L, module_spec->spec_unload_func_name); + if (lua_type(L, -1) != LUA_TFUNCTION || lua_type(L, -2) != LUA_TFUNCTION) + { + lua_settop(L, 0); + return SCRIPT_LOAD_FUNCTION_TYPE_ERR; + } + script->lua_unload_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + script->lua_load_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + + lua_newtable(L); + script->lua_script_env_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); + + lua_settop(L, 0); + return SUCCESS; +} diff --git a/src/lua_module_manage_internal.h b/src/lua_module_manage_internal.h new file mode 100644 index 0000000..79fe560 --- /dev/null +++ b/src/lua_module_manage_internal.h @@ -0,0 +1,231 @@ +#ifndef LUA_MODULE_MANAGE_INTERNAL_H +#define LUA_MODULE_MANAGE_INTERNAL_H + +#include +#include "lua_module_manage.h" + +struct lua_state; +struct lua_module_manager; + +enum LUA_MODULE_ERR_CODE +{ + /* 加载配置到状态机中错误码 */ + SCRIPT_ERR = -400, + SCRIPT_LOAD_FILE_ERR, /* 配置拷贝至状态机过程中无法处理Lua文件 */ + SCRIPT_LOAD_FUNCTION_TYPE_ERR, /* 获取得到的函数名称不是全局函数, 无法加载 */ + /* 代码块执行过程中错误码 */ + CHUNK_ERR = -300, + CHUNK_EXECUTE_TYPE_NOT_FUNCTION, /* 执行代码块过程中根据ref_id获取得到的变量不是函数 */ + CHUNK_EXECUTE_RUN_CODE_ERR, /* 执行代码块运行错误 */ + /* 函数与全局变量操作错误码 */ + CDATA_ERR = -200, + CFUNC_BIND_NAMESPACE_CONFLICT, /* 命名空间数据类型不符 */ + CFUNC_BIND_NAME_CONFLICT, /* 绑定函数的函数名称与已有数据冲突 */ + CDATA_BIND_NAMESPACE_CONFLICT, /* 命名空间数据类型不符 */ + CDATA_BIND_NAME_CONFLICT, /* 全局变量名称与已有数据冲突 */ + CDATA_BIND_TYPE_ERR, /* 数据类型无法识别或存在异常 */ + CDATA_SET_VALUE_TYPE_UNSUPPORT, /* 使用了未识别的数据类型 */ + CDATA_PUSH_STACK_TYPE_UNKNOWN, /* 入栈数据无法识别数据类型 */ + CDATA_POP_STACK_TYPE_UNSUPPORT, /* 出栈数据类型不支持出栈 */ + /* 状态机基础操作中错误码 */ + STATE_ERR = -100, + STATE_COPY_REF_VALUE_ERR, /* 在状态机之间拷贝数据过程中出现异常 */ + /* 通用返回值 */ + PARAM_ERR = -1, /* 传入参数错误, 可能是指针为空或类型不符合 */ + SUCCESS = 0, /* 运行成功 */ +}; + +/* ***** ***** ***** ***** ***** ***** */ +struct lua_state *lua_state_new(struct lua_module_manager *lua_mod_mgr); +void lua_state_free(struct lua_state *state); +struct lua_module_manager *lua_state_get_lua_module_manager(struct lua_state *state); +int lua_state_copy_ref_value(struct lua_state *to, struct lua_state *from); + +/* ***** ***** ***** ***** ***** ***** */ +struct lua_module_spec +{ + char *spec_file_path; /* 插件需要使用的文件名 */ + char *spec_load_func_name; /* 加载插件需要调用的函数名称 */ + char *spec_unload_func_name; /* 卸载插件需要调用的函数名称 */ +}; +struct lua_module_spec *lua_module_config_file_load(const char *config_file_name, size_t *spec_num); +void lua_module_spec_free(struct lua_module_spec spec[], size_t spec_num); + +/* ***** ***** ***** ***** ***** ***** */ +/* 需要注册至lua中的函数 */ +typedef int (*lua_cbind_func)(struct lua_state *state); +struct lua_bind_func_spec +{ + lua_cbind_func func; /* 注册函数原型 */ + char *func_name; /* 注册至lua中的函数名称 */ + char *space_name; /* 注册至lua中的命名空间名称 */ +}; +int lua_cbinding_function(struct lua_state *state, struct lua_bind_func_spec bind_function[], size_t bind_func_num); + +enum LUA_DATATYPE +{ + DATATYPE_BEGIN = 0, + DATATYPE_NIL, /* nil类型 */ + DATATYPE_BOOL, /* bool类型 */ + DATATYPE_INT, /* int类型 */ + DATATYPE_NUM, /* double类型 */ + DATATYPE_STRING, /* 字符串类型 */ + /* 以下类型不能用于全局变量注册 */ + DATATYPE_BUFF, /* 传递报文payload时使用 */ + DATATYPE_TABLE, /* table类型 */ + DATATYPE_POINTER, /* 指针类型 */ + DATATYPE_CONTEXT, /* context上下文类型 */ + DATATYPE_LUA_TABLE, /* 此类型用于在lua之间翻译传递数据 */ + DATATYPE_FUNCTION, /* 函数类型 */ + DATATYPE_END +}; + +/* 需要注册至lua状态机中的数据 */ +struct lua_bind_data_spec +{ + enum LUA_DATATYPE data_type; /* 注册的数据类型 */ + char *data_value; /* 注册数数据值 */ + char *data_name; /* 注册的数据名称 */ + char *space_name; /* 注册至lua中的命名空间名称 */ +}; +int lua_cbinding_data(struct lua_state *state, struct lua_bind_data_spec bind_data[], size_t bind_data_num); + +/* ***** ***** ***** ***** ***** ***** */ +struct lua_context; +struct lua_context *lua_context_new(struct lua_state *state); +struct lua_context *lua_context_new_with_ref_id(struct lua_state *state, int ref_id); +void lua_context_free(struct lua_context *context); +void lua_context_push_stack(struct lua_context *context); +int lua_context_check_if_context(void *context); + +/* ***** ***** ***** ***** ***** ***** */ +struct lua_ctable; +struct lua_cdata +{ + enum LUA_DATATYPE type; + size_t data_len; /* 只有在类型为buff或function时使用此标识 */ + union + { + int bool; + int integer; + double number; + char *string; + + char *buff; + int table; + void *pointer; + struct lua_context *context; + void *function; + struct lua_ctable *ctable; + }; +}; +struct lua_cdata *lua_cdata_new(void); +void lua_cdata_free(struct lua_cdata *cdata); +int lua_cdata_data_set(struct lua_cdata *cdata, enum LUA_DATATYPE type, void *value_p, int value_i); +int lua_cdata_push_stack(struct lua_state *state, struct lua_cdata *cdata); +int lua_cdata_pop_stack(struct lua_state *state, struct lua_cdata *cdata); + +/* ***** ***** ***** ***** ***** ***** */ +int lua_chunk_execute(struct lua_state *state, int fn_ref_id, struct lua_cdata param[], size_t param_num, struct lua_cdata returnvalue[], size_t r_num, char *errlog, size_t err_len); + +struct lua_load_script +{ + int lua_load_fn_ref_id; + int lua_unload_fn_ref_id; + int lua_script_env_ref_id; +}; +int lua_load_script_load_single_specific(struct lua_load_script *load_script, struct lua_state *state, struct lua_module_spec *module_spec); + +struct lua_fn_arg_pair +{ + struct lua_fn_arg_pair *next; + struct lua_module_manager *lua_mod_mgr; + int lua_fn_ref_id; + int lua_arg_ref_id; +}; + +/* +struct lua_mq_dispatch_arg +{ + struct lua_mq_dispatch_arg *next; + struct lua_module_manage *module_manage; + int topic_id; + int lua_mq_dispatch_fn_ref_id; + int lua_mq_dispatch_arg_ref_id; +}; + +struct lua_mq_msg_free_arg +{ + struct lua_mq_msg_free_arg *next; + struct lua_module_manage *module_manage; + int topic_id; + int lua_mq_msg_free_fn_ref_id; + int lua_mq_msg_free_arg_ref_id; +}; + +struct lua_mq_on_msg_arg +{ + struct lua_mq_on_msg_arg *next; + struct lua_module_manage *module_manage; + int topic_id; + int lua_mq_on_msg_fn_ref_id; + int lua_mq_on_msg_arg_ref_id; +}; + +struct lua_on_packet_stage_callback_arg{ + struct lua_on_packet_stage_callback_arg * next; + struct lua_module_manage * module_manage; + int lua_on_packet_stage_fn_ref_id; + int lua_on_packet_stage_arg_ref_id; +}; + +struct lua_on_session_callback_arg +{ + struct lua_on_session_callback_arg * next; + struct lua_module_manage * module_manage; + int lua_on_session_fn_ref_id; + int lua_on_session_arg_ref_id; +}; + +struct lua_on_tcp_stream_callback_arg +{ + struct lua_on_tcp_stream_callback_arg * next; + struct lua_module_manage * module_manage; + int lua_on_tcp_stream_fn_ref_id; + int lua_on_tcp_stream_arg_ref_id; +}; +*/ + +struct lua_module_manager +{ + struct stellar_module_manager *mod_mgr; + + size_t state_num; + struct lua_state **state_array; + size_t load_script_num; + // struct lua_module_spec *module_spec_array; + struct lua_load_script *load_script_array; + + struct lua_fn_arg_pair *mq_dispatch_list; + struct lua_fn_arg_pair *mq_msg_free_list; + struct lua_fn_arg_pair *mq_on_msg_list; + + struct lua_fn_arg_pair *on_packet_stage_list; + struct lua_fn_arg_pair *on_session_tcp_list; + struct lua_fn_arg_pair *on_session_udp_list; + struct lua_fn_arg_pair *on_session_control_packet_list; + struct lua_fn_arg_pair *on_tcp_stream_list; + /* + struct lua_mq_dispatch_arg *mq_dispatch_list; + struct lua_mq_msg_free_arg *mq_msg_free_list; + struct lua_mq_on_msg_arg *mq_on_msg_list; + + struct lua_on_packet_stage_callback_arg *on_packet_stage_list; + struct lua_on_session_callback_arg *on_session_tcp_list; + struct lua_on_session_callback_arg *on_session_udp_list; + struct lua_on_session_callback_arg *on_session_control_packet_list; + struct lua_on_tcp_stream_callback_arg * on_tcp_stream_list; + */ +}; + +#endif \ No newline at end of file diff --git a/src/lua_plugin_cfunc.c b/src/lua_plugin_cfunc.c deleted file mode 100644 index 4115453..0000000 --- a/src/lua_plugin_cfunc.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "lua_binding_function.h" - -void *lpm_ctx_new_func(struct session *sess, void *plugin_env) -{ - if (!plugin_env) - return NULL; - struct lua_session_plugin_env *env = (struct lua_session_plugin_env *)plugin_env; - struct lua_plugin_manage *plugin_manage = env->plugin_manage; - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = (struct lua_state *)plugin_manage->state_array[thread_id]; - struct lua_context *new_context = lua_context_new(state); - - struct lua_cdata param[3] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = sess; - param[1].type = DATATYPE_TABLE; - param[1].table = env->lua_plug_env_ref_id; - param[2].type = DATATYPE_CONTEXT; - param[2].context = new_context; - - if (lua_chunk_execute(state, env->lua_ctx_new_fn_ref_id, param, 3, NULL, 0, NULL, 0)) - { - lua_context_free(new_context); - return NULL; - } - return (void *)new_context; -} - -void lpm_ctx_free_func(struct session *sess, void *sess_ctx, void *plugin_env) -{ - if (!plugin_env) - return; - struct lua_session_plugin_env *env = (struct lua_session_plugin_env *)plugin_env; - struct lua_plugin_manage *plugin_manage = env->plugin_manage; - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[3] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = sess; - param[1].type = DATATYPE_CONTEXT; - param[1].context = (struct lua_context *)sess_ctx; - param[2].type = DATATYPE_TABLE; - param[2].table = env->lua_plug_env_ref_id; - - lua_chunk_execute(state, env->lua_ctx_free_fn_ref_id, param, 3, NULL, 0, NULL, 0); - lua_context_free((struct lua_context *)sess_ctx); - return; -} - -void lpm_session_message_free_func(struct session *sess, void *msg, void *msg_free_arg) -{ - if (!msg_free_arg) - return; - struct lua_message_free_arg *free_arg = (struct lua_message_free_arg *)msg_free_arg; - struct lua_plugin_manage *plugin_manage = free_arg->plugin_manage; - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[3] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = sess; - param[1].type = DATATYPE_CONTEXT; - param[1].context = (struct lua_context *)msg; - param[2].type = DATATYPE_TABLE; - param[2].table = free_arg->lua_msg_free_arg_ref_id; - - lua_chunk_execute(state, free_arg->lua_msg_free_fn_ref_id, param, 3, NULL, 0, NULL, 0); - lua_context_free((struct lua_context *)msg); - return; -} - -void lpm_on_session_msg_func(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_env) -{ - if (!plugin_env) - return; - - struct lua_session_plugin_env *env = (struct lua_session_plugin_env *)plugin_env; - struct lua_plugin_manage *plugin_manage = env->plugin_manage; - struct lua_on_message_fn *on_message = hash_find_on_msg_fn(plugin_manage->on_session_message_hashlist, topic_id, env->session_plugin_id); - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[5] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = sess; - param[1].type = DATATYPE_INT; - param[1].integer = topic_id; - /* 这里是不是有更好的办法 */ - struct lua_context *context = (struct lua_context *)msg; - if (context && context->magic_code == context_magic_code) - { - param[2].type = DATATYPE_CONTEXT; - param[2].context = context; - } - else - { - param[2].type = DATATYPE_POINTER; - param[2].pointer = (void *)msg; - } - param[3].type = DATATYPE_CONTEXT; - param[3].context = (struct lua_context *)sess_ctx; - param[4].type = DATATYPE_TABLE; - param[4].table = env->lua_plug_env_ref_id; - - lua_chunk_execute(state, on_message->lua_on_msg_fn_ref_id, param, 5, NULL, 0, NULL, 0); - return; -} - -void lpm_on_packet_func(struct packet *pkt, unsigned char ip_protocol, void *plugin_env) -{ - if (!plugin_env) - return; - - struct lua_packet_plugin_env *env = (struct lua_packet_plugin_env *)plugin_env; - struct lua_plugin_manage *plugin_manage = env->plugin_manage; - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[3] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = pkt; - param[1].type = DATATYPE_INT; - param[1].integer = (int)ip_protocol; - param[2].type = DATATYPE_TABLE; - param[2].table = env->lua_plug_env_ref_id; - - lua_chunk_execute(state, env->lua_on_packet_fn_ref_id, param, 3, NULL, 0, NULL, 0); - return; -} - -void lpm_packet_message_free_func(struct packet *pkt, void *msg, void *msg_free_arg) -{ - if (!msg_free_arg) - return; - struct lua_message_free_arg *free_arg = (struct lua_message_free_arg *)msg_free_arg; - struct lua_plugin_manage *plugin_manage = free_arg->plugin_manage; - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[3] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = pkt; - param[1].type = DATATYPE_CONTEXT; - param[1].context = (struct lua_context *)msg; - param[2].type = DATATYPE_TABLE; - param[2].table = free_arg->lua_msg_free_arg_ref_id; - - lua_chunk_execute(state, free_arg->lua_msg_free_fn_ref_id, param, 3, NULL, 0, NULL, 0); - lua_context_free((struct lua_context *)msg); - return; -} - -void lpm_on_packet_msg_func(struct packet *pkt, int topic_id, const void *msg, void *plugin_env) -{ - if (!plugin_env) - return; - - struct lua_packet_plugin_env *env = (struct lua_packet_plugin_env *)plugin_env; - struct lua_plugin_manage *plugin_manage = env->plugin_manage; - struct lua_on_message_fn *on_message = hash_find_on_msg_fn(plugin_manage->on_packet_message_hashlist, topic_id, env->packet_plugin_id); - struct stellar *st = plugin_manage->st; - - int thread_id = stellar_get_current_thread_id(st); - struct lua_state *state = plugin_manage->state_array[thread_id]; - - struct lua_cdata param[4] = {0}; - param[0].type = DATATYPE_POINTER; - param[0].pointer = pkt; - param[1].type = DATATYPE_INT; - param[1].integer = topic_id; - /* 这里是不是有更好的办法 */ - struct lua_context *context = (struct lua_context *)msg; - if (context && context->magic_code == context_magic_code) - { - param[2].type = DATATYPE_CONTEXT; - param[2].context = (struct lua_context *)msg; - } - else - { - param[2].type = DATATYPE_POINTER; - param[2].pointer = (void *)msg; - } - param[3].type = DATATYPE_TABLE; - param[3].table = env->lua_plug_env_ref_id; - - lua_chunk_execute(state, on_message->lua_on_msg_fn_ref_id, param, 5, NULL, 0, NULL, 0); - return; -} \ No newline at end of file diff --git a/src/lua_plugin_manage.c b/src/lua_plugin_manage.c deleted file mode 100644 index 81ab59a..0000000 --- a/src/lua_plugin_manage.c +++ /dev/null @@ -1,931 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "lua_binding_function.h" - -struct lua_bind_function_spec lua_bind_function[] = { - {lua_get_worker_thread_num, "get_worker_thread_num", "stellar"}, - {lua_get_current_thread_id, "get_current_thread_id", "stellar"}, - {lua_get_stellar_pointer, "get_stellar", "stellar"}, - - {lua_session_plugin_regist, "register", "session_plugin"}, - {lua_packet_plugin_regist, "register", "packet_plugin"}, - - {lua_session_get_type, "get_type", "session"}, - - {lua_packet_mq_create_topic, "create_topic", "packet_mq"}, - {lua_packet_mq_get_topic_id, "get_topic_id", "packet_mq"}, - {lua_packet_mq_update_topic, "update_topic", "packet_mq"}, - {lua_packet_mq_destory_topic, "destory_topic", "packet_mq"}, - {lua_packet_mq_subscribe_topic, "subscribe_topic", "packet_mq"}, - {lua_packet_mq_publish_message, "publish_message", "packet_mq"}, - - {lua_session_mq_create_topic, "create_topic", "session_mq"}, - {lua_session_mq_get_topic_id, "get_topic_id", "session_mq"}, - {lua_session_mq_update_topic, "update_topic", "session_mq"}, - {lua_session_mq_destory_topic, "destory_topic", "session_mq"}, - {lua_session_mq_subscribe_topic, "subscribe_topic", "session_mq"}, - {lua_session_mq_topic_is_active, "topic_is_active", "session_mq"}, - {lua_session_mq_publish_message, "publish_message", "session_mq"}, - {lua_session_mq_ignore_message, "ignore_message", "session_mq"}, - {lua_session_mq_unignore_message, "unignore_message", "session_mq"}, - - {lua_session_get0_current_payload, "get_payload", "session"}, - {NULL, NULL, NULL}, -}; - -struct lua_bind_data_spec lua_bind_data[] = { - {DATATYPE_BOOL, "true", "test_data_bool", "plugin_manage"}, - {DATATYPE_INT, "1000", "test_data_int", "plugin_manage"}, - {DATATYPE_NUM, "100.001", "test_data_double", "plugin_manage"}, - {DATATYPE_STRING, "this is a string test", "test_data_string", "plugin_manage"}, - {DATATYPE_END, NULL, NULL, NULL}, -}; - -struct lua_state -{ - lua_State *state; -}; - -/* ***** ***** ***** ***** ***** ***** */ -/* cbinding */ -/* ***** ***** ***** ***** ***** ***** */ -static int lua_cbinding_single_function(struct lua_state *state, struct lua_bind_function_spec *function_spec) -{ - if (!state || !function_spec || !function_spec->function || !function_spec->func_name) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - if (function_spec->space_name) - { - lua_getglobal(L, function_spec->space_name); - if (lua_type(L, -1) == LUA_TNIL) - { - lua_newtable(L); - lua_setglobal(L, function_spec->space_name); - lua_settop(L, 0); - lua_getglobal(L, function_spec->space_name); - } - else - { - if (lua_type(L, -1) != LUA_TTABLE) - { - lua_settop(L, 0); - return BIND_NAMESPACE_TYPE_ERR; - } - - lua_getfield(L, -1, function_spec->func_name); - if (lua_type(L, -1) != LUA_TNIL) - { - lua_settop(L, 0); - return BIND_FUNCTION_TYPE_ERR; - } - lua_pop(L, 1); - } - lua_pushcfunction(L, (lua_CFunction)function_spec->function); - lua_setfield(L, -2, function_spec->func_name); - } - else - { - lua_getglobal(L, function_spec->func_name); - if (lua_type(L, -1) != LUA_TNIL) - { - lua_settop(L, 0); - return BIND_FUNCTION_TYPE_ERR; - } - lua_pop(L, 1); - - lua_pushcfunction(L, (lua_CFunction)function_spec->function); - lua_setglobal(L, function_spec->func_name); - } - - lua_settop(L, 0); - return SUCCESS; -} - -static int lua_cbinding_single_data(struct lua_state *state, struct lua_bind_data_spec *data_spec) -{ - if (!state || !data_spec || !data_spec->data_value || !data_spec->data_name) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - if (data_spec->space_name) - { - lua_getglobal(L, data_spec->space_name); - if (lua_gettop(L) == 0 || lua_type(L, -1) == LUA_TNIL) - { - lua_newtable(L); - lua_setglobal(L, data_spec->space_name); - lua_settop(L, 0); - lua_getglobal(L, data_spec->space_name); - } - else - { - if (lua_type(L, -1) != LUA_TTABLE) - { - lua_settop(L, 0); - return BIND_NAMESPACE_TYPE_ERR; - } - - lua_getfield(L, -1, data_spec->data_name); - if (lua_type(L, -1) != LUA_TNIL) - { - lua_settop(L, 0); - return BIND_DATA_TYPE_ERR; - } - lua_pop(L, 1); - } - - switch (data_spec->data_type) - { - case DATATYPE_BOOL: - if (strstr(data_spec->data_value, "true") || strstr(data_spec->data_value, "TRUE")) - lua_pushboolean(L, 1); - else if (strstr(data_spec->data_value, "false") || strstr(data_spec->data_value, "FALSE")) - lua_pushboolean(L, 0); - break; - case DATATYPE_INT: - lua_pushinteger(L, atoi(data_spec->data_value)); - break; - case DATATYPE_NUM: - lua_pushnumber(L, (lua_Number)atof(data_spec->data_value)); - break; - case DATATYPE_STRING: - lua_pushstring(L, (const char *)data_spec->data_value); - break; - default: - /* 其他类型不支持 */ - lua_settop(L, 0); - return BIND_DATA_TYPE_UNKNOWN; - } - lua_setfield(L, -2, data_spec->data_name); - } - else - { - lua_getglobal(L, data_spec->data_name); - if (lua_type(L, -1) != LUA_TNIL) - { - lua_settop(L, 0); - return BIND_DATA_TYPE_ERR; - } - lua_pop(L, 1); - - switch (data_spec->data_type) - { - case DATATYPE_BOOL: - if (strstr(data_spec->data_value, "true") || strstr(data_spec->data_value, "TRUE")) - lua_pushboolean(L, 1); - else if (strstr(data_spec->data_value, "false") || strstr(data_spec->data_value, "FALSE")) - lua_pushboolean(L, 0); - break; - case DATATYPE_INT: - lua_pushinteger(L, atoi(data_spec->data_value)); - break; - case DATATYPE_NUM: - lua_pushnumber(L, (lua_Number)atof(data_spec->data_value)); - break; - case DATATYPE_STRING: - lua_pushstring(L, (const char *)data_spec->data_value); - break; - default: - /* 其他类型不支持 */ - lua_settop(L, 0); - return BIND_DATA_TYPE_UNKNOWN; - } - lua_setglobal(L, data_spec->data_name); - } - - lua_settop(L, 0); - return SUCCESS; -} - -int lua_cbinding_function(struct lua_state *state, struct lua_bind_function_spec bind_function[], size_t bind_func_num) -{ - int failed_count = 0; - for (unsigned index = 0; index < bind_func_num; index++) - { - if (lua_cbinding_single_function(state, &bind_function[index])) - failed_count++; - } - return failed_count; -} - -int lua_cbinding_data(struct lua_state *state, struct lua_bind_data_spec bind_data[], size_t bind_data_num) -{ - int failed_count = 0; - for (unsigned index = 0; index < bind_data_num; index++) - { - if (lua_cbinding_single_data(state, &bind_data[index])) - failed_count++; - } - return failed_count; -} - -/* ***** ***** ***** ***** ***** ***** */ -/* context */ -/* ***** ***** ***** ***** ***** ***** */ -const char *context_magic_code = "ctx_code"; -struct lua_context *lua_context_new(struct lua_state *state) -{ - if (!state) - return NULL; - lua_State *L = (lua_State *)state; - struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context)); - new_context->magic_code = context_magic_code; - new_context->state = state; - - lua_newtable(L); - int ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (ref_id == LUA_REFNIL) - return NULL; - new_context->lua_context_ref_id = ref_id; - return new_context; -} - -void lua_context_free(struct lua_context *context) -{ - if (!context) - return; - luaL_unref((lua_State *)context->state, LUA_REGISTRYINDEX, context->lua_context_ref_id); - free(context); - return; -} - -void lua_context_push_stack(struct lua_context *context) -{ - if (!context) - return; - if (context->lua_context_ref_id) - lua_rawgeti((lua_State *)context->state, LUA_REGISTRYINDEX, context->lua_context_ref_id); - return; -} - -/* ***** ***** ***** ***** ***** ***** */ -/* trans data between lua table and C */ -/* ***** ***** ***** ***** ***** ***** */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -static int lua_function_writer(lua_State *state, const void *p, size_t sz, void *ud) -{ - /* TODO: 这个函数在lua中会被大量调用, 频繁的realloc可能会导致内存碎片化, 后续调整一下内存分配机制 */ - struct lua_cdata *data = (struct lua_cdata *)ud; - data->type = DATATYPE_FUNCTION; - if (!data->function) - data->function = (void *)calloc(1, sizeof(sz)); - else - data->function = (void *)realloc(data->function, (data->data_len + sz)); - memcpy((data->function + data->data_len), p, sz); - data->data_len += sz; - return 0; -} - -static const char *lua_function_reader(lua_State *state, void *ud, size_t *sz) -{ - struct lua_cdata *data = (struct lua_cdata *)ud; - *sz = data->data_len; - return (const char *)data->function; -} -#pragma GCC diagnostic pop - -struct lua_cdata *lua_cdata_new(void) -{ - struct lua_cdata *new_data = (struct lua_cdata *)calloc(1, sizeof(struct lua_cdata)); - memset(new_data, 0, sizeof(struct lua_cdata)); - return new_data; -} - -static void lua_cdata_inner_data_free(struct lua_cdata *cdata) -{ - if (!cdata) - return; - cdata->type = 0; - cdata->data_len = 0; - switch (cdata->type) - { - case DATATYPE_STRING: - free(cdata->string); - break; - case DATATYPE_LUA_TABLE: - lua_ctable_free(cdata->ctable); - break; - case DATATYPE_FUNCTION: - free(cdata->function); - break; - default: - break; - } - return; -} - -void lua_cdata_free(struct lua_cdata *cdata) -{ - lua_cdata_inner_data_free(cdata); - if (cdata) - free(cdata); - return; -} - -int lua_cdata_push_stack(struct lua_state *state, struct lua_cdata *cdata) -{ - if (!state || !cdata) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - switch (cdata->type) - { - case DATATYPE_NIL: - lua_pushnil(L); - break; - case DATATYPE_BOOL: - lua_pushboolean(L, cdata->bool); - break; - case DATATYPE_INT: - lua_pushinteger(L, cdata->integer); - break; - case DATATYPE_NUM: - lua_pushnumber(L, cdata->number); - break; - case DATATYPE_STRING: - lua_pushstring(L, cdata->string); - break; - case DATATYPE_TABLE: - if (cdata->table) - lua_rawgeti(L, LUA_REGISTRYINDEX, cdata->table); - break; - case DATATYPE_LUA_TABLE: - lua_ctable_push_stack(state, cdata->ctable); - break; - case DATATYPE_POINTER: - lua_pushlightuserdata(L, (void *)cdata->pointer); - break; - case DATATYPE_CONTEXT: - lua_context_push_stack(cdata->context); - break; - case DATATYPE_FUNCTION: - lua_load(L, lua_function_reader, (void *)cdata, NULL, NULL); - break; - default: - return DATA_TYPE_UNKNOWN; - } - return SUCCESS; -} - -int lua_cdata_pop_stack(struct lua_state *state, struct lua_cdata *cdata) -{ - if (!state || !cdata) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - lua_cdata_inner_data_free(cdata); - switch (lua_type(L, -1)) - { - case LUA_TNIL: - cdata->type = DATATYPE_NIL; - break; - case LUA_TBOOLEAN: - cdata->type = DATATYPE_BOOL; - cdata->bool = lua_toboolean(L, -1); - break; - case LUA_TLIGHTUSERDATA: - cdata->type = DATATYPE_POINTER; - cdata->pointer = (void *)lua_topointer(L, -1); - break; - case LUA_TNUMBER: - cdata->type = DATATYPE_NUM; - cdata->number = lua_tonumber(L, -1); - int try_int = (int)cdata->number; - if ((double)try_int == cdata->number) - { - cdata->type = DATATYPE_INT; - cdata->integer = lua_tointeger(L, -1); - } - break; - case LUA_TSTRING: - cdata->type = DATATYPE_STRING; - cdata->string = (char *)strdup(lua_tostring(L, -1)); - break; - case LUA_TTABLE: - cdata->type = DATATYPE_LUA_TABLE; - cdata->ctable = lua_ctable_new(); - lua_ctable_pop_stack(state, cdata->ctable); - break; - case LUA_TFUNCTION: - cdata->type = DATATYPE_FUNCTION; - lua_dump(L, lua_function_writer, cdata, 0); - break; - case LUA_TUSERDATA: - cdata->type = DATATYPE_POINTER; - cdata->pointer = (void *)lua_topointer(L, -1); - break; - default: - return DATA_TYPE_UNKNOWN; - } - lua_pop(L, 1); - return SUCCESS; -} - -struct lua_ctable *lua_ctable_new(void) -{ - struct lua_ctable *new_table = (struct lua_ctable *)calloc(1, sizeof(struct lua_ctable)); - memset(new_table, 0, sizeof(struct lua_ctable)); - return new_table; -} - -void lua_ctable_free(struct lua_ctable *ctable) -{ - if (!ctable) - return; - for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) - { - lua_cdata_free(ctable->array_data[array_index]); - } - for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) - { - lua_cnode_free(ctable->node_data[node_index]); - } - if (ctable->array_data) - free(ctable->array_data); - if (ctable->node_data) - free(ctable->node_data); - free(ctable); - return; -} - -int lua_ctable_push_stack(struct lua_state *state, struct lua_ctable *ctable) -{ - if (!state || !ctable) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - lua_newtable(L); - for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) - { - lua_pushinteger(L, (array_index + 1)); - lua_cdata_push_stack(state, ctable->array_data[array_index]); - lua_settable(L, -3); - } - for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) - { - if (ctable->node_data[node_index]->node_string_key) - lua_pushstring(L, ctable->node_data[node_index]->node_string_key); - else - lua_pushinteger(L, ctable->node_data[node_index]->node_integer_key); - lua_cdata_push_stack(state, ctable->node_data[node_index]->node_data); - lua_settable(L, -3); - } - - return SUCCESS; -} - -int lua_ctable_pop_stack(struct lua_state *state, struct lua_ctable *ctable) -{ - if (!state || !ctable) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - /* 获取table长度 */ - ctable->array_size = (size_t)lua_rawlen(L, -1); - lua_pushnil(L); - while (lua_next(L, -2)) - { - ctable->node_size++; - if (lua_type(L, -2) == LUA_TNUMBER) - { - int numkey = lua_tointeger(L, -2); - if (numkey > 0 && numkey <= (int)ctable->array_size) - ctable->node_size--; - } - lua_pop(L, 1); - } - - ctable->array_data = (struct lua_cdata **)calloc(ctable->array_size, sizeof(struct lua_cdata *)); - for (unsigned array_index = 0; array_index < ctable->array_size; array_index++) - { - ctable->array_data[array_index] = lua_cdata_new(); - } - ctable->node_data = (struct lua_cnode **)calloc(ctable->node_size, sizeof(struct lua_cnode *)); - for (unsigned node_index = 0; node_index < ctable->node_size; node_index++) - { - ctable->node_data[node_index] = lua_cnode_new(); - } - - /* 依次获取数据 */ - int key_index = 0; - lua_pushnil(L); - while (lua_next(L, -2)) - { - if (lua_type(L, -2) == LUA_TNUMBER) - { - int numkey = lua_tointeger(L, -2); - if (numkey > 0 && numkey <= (int)ctable->array_size) - lua_cdata_pop_stack(state, ctable->array_data[numkey - 1]); - else - { - lua_cdata_pop_stack(state, ctable->node_data[key_index]->node_data); - ctable->node_data[key_index]->node_integer_key = lua_tointeger(L, -1); - ++key_index; - } - } - else if (lua_type(L, -2) == LUA_TSTRING) - { - lua_cdata_pop_stack(state, ctable->node_data[key_index]->node_data); - ctable->node_data[key_index]->node_string_key = strdup((char *)lua_tostring(L, -1)); - ++key_index; - } - } - - return SUCCESS; -} - -struct lua_cnode *lua_cnode_new(void) -{ - struct lua_cnode *new_node = (struct lua_cnode *)calloc(1, sizeof(struct lua_cnode)); - memset(new_node, 0, sizeof(struct lua_cnode)); - new_node->node_data = lua_cdata_new(); - return new_node; -} - -void lua_cnode_free(struct lua_cnode *cnode) -{ - if (cnode->node_string_key) - free(cnode->node_string_key); - if (cnode->node_data) - lua_cdata_free(cnode->node_data); - free(cnode); - return; -} - -/* ***** ***** ***** ***** ***** ***** */ -/* execute one chunk */ -/* ***** ***** ***** ***** ***** ***** */ -int lua_chunk_execute( - struct lua_state *state, - int fn_ref_id, - struct lua_cdata param[], - size_t param_num, - struct lua_cdata returnvalue[], - size_t r_num, - char *errlog, - size_t err_len) -{ - if (!state || fn_ref_id <= 0 || (param_num && !param) || (r_num && !returnvalue)) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - - lua_rawgeti(L, LUA_REGISTRYINDEX, fn_ref_id); - if (lua_type(L, -1) != LUA_TFUNCTION) - { - lua_settop(L, 0); - return CHUNK_TYPE_NOT_FUNCTION; - } - - int pushret = 0; - for (unsigned param_index = 0; param_index < param_num; ++param_index) - { - if ((pushret = lua_cdata_push_stack(state, ¶m[param_index]))) - { - lua_settop(L, 0); - return pushret; - } - } - - if (lua_pcall(L, param_num, LUA_MULTRET, 0)) - { - if (errlog) - snprintf(errlog, (err_len - 1), "run script[%d] err %s\n", fn_ref_id, lua_tostring(L, -1)); - lua_settop(L, 0); - return CHUNK_RUN_CODE_FAIL; - } - - if (r_num > 0) - { - int count = lua_gettop(L); - /* 如果接收返回值数量不够, 只保留前r_num个返回值 */ - if (count > (int)r_num) - { - lua_pop(L, (count - (int)r_num)); - count = (int)r_num; - } - int pop_ret = 0; - for (int i = (count - 1); i >= 0; --i) - { - if ((pop_ret = lua_cdata_pop_stack(state, &(returnvalue[i])))) - { - lua_settop(L, 0); - return pop_ret; - } - } - } - - lua_settop(L, 0); - return SUCCESS; -} - -/* TODO: 这个hash函数是不是合适 */ -int calc_on_message_func_hash_key(int topic_id, int plugin_id) -{ - return (((uint32_t)plugin_id << 3) + (uint32_t)topic_id) % HASH_MAX_NUM; -} - -struct lua_on_message_fn *hash_on_msg_fn_insert(struct lua_on_message_fn msg_fn_hashlist[], int topic_id, int plugin_id) -{ - int hash_key = calc_on_message_func_hash_key(topic_id, plugin_id); - struct lua_on_message_fn *insert_positon = &msg_fn_hashlist[hash_key]; - while ((insert_positon->hash_on_use - HASH_MAX_NUM) > 0) - { - if (insert_positon->hash_on_use % HASH_MAX_NUM == (HASH_MAX_NUM - 1)) - insert_positon = &msg_fn_hashlist[0]; - else - insert_positon++; - /* 没有空位置了 */ - if (insert_positon->hash_on_use % HASH_MAX_NUM == hash_key) - return NULL; - } - insert_positon->hash_on_use += (HASH_MAX_NUM + 1); - insert_positon->topic_id = topic_id; - insert_positon->plugin_id = plugin_id; - return insert_positon; -} - -struct lua_on_message_fn *hash_find_on_msg_fn(struct lua_on_message_fn msg_fn_hashlist[], int topic_id, int plugin_id) -{ - int hash_key = calc_on_message_func_hash_key(topic_id, plugin_id); - struct lua_on_message_fn *find_position = &msg_fn_hashlist[hash_key]; - if ((find_position->hash_on_use - HASH_MAX_NUM) < 0) - return NULL; - while (find_position) - { - if (find_position->topic_id == topic_id && find_position->plugin_id == plugin_id) - { - return find_position; - } - if (find_position->hash_on_use % HASH_MAX_NUM == (HASH_MAX_NUM - 1)) - find_position = &msg_fn_hashlist[0]; - else - find_position++; - if ((find_position->hash_on_use % HASH_MAX_NUM == hash_key) || (find_position->hash_on_use - HASH_MAX_NUM) < 0) - break; - } - return NULL; -} - -#define LUA_GLOBAL_VALUE_REF_ID (LUA_RIDX_LAST + 2) - -static inline struct lua_state *thread_state_init(int thread_id, struct stellar *st, struct lua_plugin_manage *plugin_manage) -{ - lua_State *new_L = luaL_newstate(); - luaL_openlibs(new_L); - - lua_newtable(new_L); - lua_pushinteger(new_L, thread_id); - lua_setfield(new_L, -2, LUA_GLOBAL_THREAD_ID_KEY); - lua_pushlightuserdata(new_L, st); - lua_setfield(new_L, -2, LUA_GLOBAL_STELLAR_POINTER); - lua_pushlightuserdata(new_L, plugin_manage); - lua_setfield(new_L, -2, LUA_GLOBAL_PLUGIN_MANGE_POINTER); - int global_ref_id = luaL_ref(new_L, LUA_REGISTRYINDEX); - printf("set global ref id is %d\n", global_ref_id); - lua_settop(new_L, 0); - - struct lua_state *new_state = (struct lua_state *)new_L; - lua_cbinding_function(new_state, lua_bind_function, (sizeof(lua_bind_function) / sizeof(struct lua_bind_function_spec))); - lua_cbinding_data(new_state, lua_bind_data, (sizeof(lua_bind_data) / sizeof(struct lua_bind_data_spec))); - return new_state; -} - -/* -int lua_state_get_thread_id(struct lua_state * state) -{ - lua_State * L = (lua_State *)state; - lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_GLOBAL_VALUE_REF_ID); - int thread_id = -1; - if ( lua_getfield(L, -1, LUA_GLOBAL_THREAD_ID_KEY) == LUA_TNUMBER ) - thread_id = lua_tointeger(L, -1); - lua_pop(L, 2); - return thread_id; -} - -struct stellar * lua_state_get_stellar(struct lua_state * state) -{ - lua_State * L = (lua_State *)state; - lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_GLOBAL_VALUE_REF_ID); - struct stellar * st = NULL; - if ( lua_getfield(L, -1, LUA_GLOBAL_STELLAR_POINTER) == LUA_TLIGHTUSERDATA ) - st = (struct stellar *)lua_topointer(L, -1); - lua_pop(L, 2); - return st; -} -*/ - -struct lua_plugin_manage *lua_state_get_plugin_manage(struct lua_state *state) -{ - lua_State *L = (lua_State *)state; - lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_GLOBAL_VALUE_REF_ID); - struct lua_plugin_manage *plugin_manage = NULL; - if (lua_getfield(L, -1, LUA_GLOBAL_PLUGIN_MANGE_POINTER) == LUA_TLIGHTUSERDATA) - plugin_manage = (struct lua_plugin_manage *)lua_topointer(L, -1); - lua_pop(L, 2); - return plugin_manage; -} - -static int lua_state_load_one_specific( - struct lua_state *state, - struct lua_config_spec *spec, - struct lua_load_script *script, - struct stellar *st, - char *errlog, - size_t errlog_len) -{ - if (!state || !spec || !script) - return PARAM_ERR; - lua_State *L = (lua_State *)state; - if (access(spec->spec_file_path, F_OK) || luaL_loadfile(L, spec->spec_file_path)) - return STATE_LOAD_FILE_ERR; - if (lua_pcall(L, 0, 0, 0)) - { - snprintf(errlog, (errlog_len - 1), "load spec[%s] fail err is %s\n", spec->spec_file_path, lua_tostring(L, -1)); - lua_settop(L, 0); - return STATE_LOAD_FILE_ERR; - } - - /* 创建on_load函数及on_unload函数的引用 */ - lua_getglobal(L, spec->spec_load_func_name); - if (lua_type(L, -1) != LUA_TFUNCTION) - { - snprintf(errlog, (errlog_len - 1), "spec[%s] funcname[%s] is not a function\n", spec->spec_file_path, spec->spec_load_func_name); - return STATE_REF_TYPE_ERR; - } - script->lua_load_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (script->lua_load_fn_ref_id <= 0) - { - snprintf(errlog, (errlog_len - 1), "spec[%s]%s create load func ref id is %d\n", spec->spec_file_path, spec->spec_load_func_name, script->lua_load_fn_ref_id); - return STATE_CREATE_REF_FAIL; - } - lua_getglobal(L, spec->spec_unload_func_name); - if (lua_type(L, -1) != LUA_TFUNCTION) - { - snprintf(errlog, (errlog_len - 1), "spec[%s] funcname[%s] is not a function\n", spec->spec_file_path, spec->spec_unload_func_name); - return STATE_REF_TYPE_ERR; - } - script->lua_unload_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (script->lua_unload_fn_ref_id <= 0) - { - snprintf(errlog, (errlog_len - 1), "spec[%s]%s create load func ref id is %d\n", spec->spec_file_path, spec->spec_unload_func_name, script->lua_unload_fn_ref_id); - return STATE_CREATE_REF_FAIL; - } - - /* 创建依赖于该script的script_env, 并调用on_load函数 */ - lua_newtable(L); - script->lua_script_env_ref_id = luaL_ref(L, LUA_REGISTRYINDEX); - if (script->lua_script_env_ref_id <= 0) - { - snprintf(errlog, (errlog_len - 1), "spec[%s] create script env failed, ref is %d\n", spec->spec_file_path, script->lua_script_env_ref_id); - return STATE_CREATE_REF_FAIL; - } - - struct lua_cdata param[2]; - param[0].type = DATATYPE_POINTER; - param[0].pointer = (void *)st; - param[1].type = DATATYPE_TABLE; - param[1].table = script->lua_script_env_ref_id; - char exec_err[1024] = {0}; - int exec_ret = lua_chunk_execute(state, script->lua_load_fn_ref_id, param, 2, NULL, 0, exec_err, sizeof(exec_err)); - if (exec_ret) - { - snprintf(errlog, (errlog_len - 1), "spec[%s]%s call fail, err num %d, err %s\n", spec->spec_file_path, spec->spec_load_func_name, exec_ret, exec_err); - return STATE_CALL_LOAD_FAILED; - } - - return SUCCESS; -}; - -// static UT_icd lua_session_plugin_icd = {sizeof(struct lua_session_plugin_env), NULL, NULL, NULL}; -// static UT_icd lua_packet_plugin_icd = {sizeof(struct lua_packet_plugin_env), NULL, NULL, NULL}; -// static UT_icd lua_message_free_icd = {sizeof(struct lua_message_free_arg), NULL, NULL, NULL}; - -struct lua_plugin_manage *lua_plugin_manage_init( - struct stellar *st, - struct lua_config_spec specific[], - size_t specific_num) -{ - if (!st) - return NULL; - char errlog[1024] = {0}; - - struct lua_plugin_manage *new_plugin_manage = (struct lua_plugin_manage *)calloc(1, sizeof(struct lua_plugin_manage)); - memset(new_plugin_manage, 0, sizeof(struct lua_plugin_manage)); - - new_plugin_manage->st = st; - - int thread_count = stellar_get_worker_thread_num(st); - if (thread_count <= 0) - return new_plugin_manage; - new_plugin_manage->state_num = thread_count; - new_plugin_manage->state_array = (struct lua_state **)calloc(thread_count, sizeof(struct lua_state *)); - memset(new_plugin_manage->state_array, 0, thread_count * sizeof(struct lua_state *)); - for (int thread_index = 0; thread_index < thread_count; thread_index++) - { - new_plugin_manage->state_array[thread_index] = thread_state_init(thread_index, st, new_plugin_manage); - } - - for (unsigned on_message_index = 0; on_message_index < HASH_MAX_NUM; on_message_index++) - { - new_plugin_manage->on_session_message_hashlist[on_message_index].hash_on_use = on_message_index; - new_plugin_manage->on_packet_message_hashlist[on_message_index].hash_on_use = on_message_index; - } - - if (specific_num == 0) - return new_plugin_manage; - new_plugin_manage->load_script_array = (struct lua_load_script *)calloc(specific_num, sizeof(struct lua_load_script)); - new_plugin_manage->load_script_num = specific_num; - for (unsigned spec_index = 0; spec_index < specific_num; spec_index++) - { - if (lua_state_load_one_specific(new_plugin_manage->state_array[0], - &specific[spec_index], - &new_plugin_manage->load_script_array[spec_index], - st, - errlog, - sizeof(errlog))) - { - printf("%s\n", errlog); - goto err; - } - } - - lua_newtable((lua_State *)new_plugin_manage->state_array[0]); - int lua_ref_max_id = luaL_ref((lua_State *)new_plugin_manage->state_array[0], LUA_REGISTRYINDEX); - struct lua_cdata *trans_data = lua_cdata_new(); - for (int ref_index = (LUA_GLOBAL_VALUE_REF_ID + 1); ref_index < lua_ref_max_id; ref_index++) - { - lua_settop((lua_State *)new_plugin_manage->state_array[0], 0); - lua_rawgeti((lua_State *)new_plugin_manage->state_array[0], LUA_REGISTRYINDEX, ref_index); - lua_cdata_pop_stack(new_plugin_manage->state_array[0], trans_data); - for (int thread_index = 1; thread_index < thread_count; thread_index++) - { - lua_cdata_push_stack(new_plugin_manage->state_array[thread_index], trans_data); - int ref_id = luaL_ref((lua_State *)new_plugin_manage->state_array[thread_index], LUA_REGISTRYINDEX); - printf("ref to new thread, ref id is %d, %d\n", ref_index, ref_id); - } - lua_cdata_inner_data_free(trans_data); - } - luaL_unref((lua_State *)new_plugin_manage->state_array[0], LUA_REGISTRYINDEX, lua_ref_max_id); - - return new_plugin_manage; - -err: - lua_plugin_manage_exit(new_plugin_manage); - return NULL; -} - -void lua_plugin_manage_exit(struct lua_plugin_manage *lua_plug_mgr) -{ - if (!lua_plug_mgr) - return; - - for (unsigned script_index = 0; script_index < lua_plug_mgr->load_script_num; script_index++) - { - struct lua_cdata param; - param.type = DATATYPE_TABLE; - param.table = lua_plug_mgr->load_script_array[script_index].lua_script_env_ref_id; - lua_chunk_execute(lua_plug_mgr->state_array[0], lua_plug_mgr->load_script_array[script_index].lua_unload_fn_ref_id, ¶m, 1, NULL, 0, NULL, 0); - } - free(lua_plug_mgr->load_script_array); - - for (unsigned state_index = 0; state_index < lua_plug_mgr->state_num; ++state_index) - { - lua_close((lua_State *)lua_plug_mgr->state_array[state_index]); - } - free(lua_plug_mgr->state_array); - - struct lua_session_plugin_env *session_env = lua_plug_mgr->session_plugin_env_list; - while (session_env) - { - struct lua_session_plugin_env *next = session_env->next; - free(session_env); - session_env = next; - } - - struct lua_packet_plugin_env *packet_env = lua_plug_mgr->packet_plugin_env_list; - while (packet_env) - { - struct lua_packet_plugin_env *next = packet_env->next; - free(packet_env); - packet_env = next; - } - - struct lua_message_free_arg *message_free_arg = lua_plug_mgr->message_free_arg_list; - while (message_free_arg) - { - struct lua_message_free_arg *next = message_free_arg->next; - free(message_free_arg); - message_free_arg = next; - } - - free(lua_plug_mgr); - return; -} \ No newline at end of file diff --git a/src/lua_plugin_manage_internal.h b/src/lua_plugin_manage_internal.h deleted file mode 100644 index b977a04..0000000 --- a/src/lua_plugin_manage_internal.h +++ /dev/null @@ -1,217 +0,0 @@ -#ifndef LUA_PLUGIN_MANAGE_INTERNAL_H -#define LUA_PLUGIN_MANAGE_INTERNAL_H - -#include -#include "lua_plugin_manage.h" - -struct lua_state; - -enum LUA_PLUGIN_MANGE_ERR_NUM -{ - /* 状态机相关的错误码 */ - STATE_LOAD_FILE_ERR = -400, /* 状态机加载lua文件时出错, 可能原因是文件不存在或文件无法加载 */ - STATE_REF_TYPE_ERR, /* 获取函数引用ID过程中数据类型有错, 无法正常执行 */ - STATE_CREATE_REF_FAIL, /* 创建引用ID过程中失败, 无法创建refid */ - STATE_CALL_LOAD_FAILED, /* 调用on_load函数过程中运行失败 */ - STATE_CALL_UNLOAD_FAILED, /* 调用on_unload函数过程中运行失败 */ - - STATE_CREATE_ENV_FAIL, /* 在状态机中创建新的plugin_env时出现错误, 无法创建或该模块之前加载过程中的引用ID与新创建ID不同 */ - STATE_GET_UNLOAD_FAIL, /* 状态机加载unload函数时出现错误, 该函数不存在或引用ID有问题 */ - /* lua代码块运行错误码 */ - CHUNK_TYPE_NOT_FUNCTION = -300, /* 获取得到的代码块类型并非可执行的lua语句, 无法执行 */ - CHUNK_RUN_CODE_FAIL, /* 调用代码过程中运行失败, 失败的具体报错信息会保存在栈中, 通过日志输出 */ - - CHUNK_RCOUNT_ERR, /* 尝试接收返回值, 但传入接收返回值的队列长度小于实际返回值个数 */ - /* lua与C之间数据转换或操作错误码 */ - DATA_TYPE_UNKNOWN = -200, /* 无法识别的struct lua_cdata数据类型, 或在该函数中操作了不支持的数据类型 */ - DATA_TYPE_ERR, /* 获取到了错误的数据类型 */ - - DATA_PUSHSTACK_ERR, /* 数据入栈过程中遇到未知的问题 */ - DATA_POPSTACK_ERR, /* 数据从状态机中出栈过程中遇到未知的问题 */ - DATA_POPSTACK_NODATA, /* 出栈过程中栈内无数据, 导致出栈失败 */ - /* lua函数或数据绑定错误码 */ - BIND_NAMESPACE_TYPE_ERR = -100, /* 绑定或删除过程中使用命名空间, 但命名空间数据类型不符 */ - BIND_FUNCTION_TYPE_ERR, /* 绑定或删除函数过程中数据类型错误 */ - BIND_DATA_TYPE_ERR, /* 绑定或删除全局变量过程中数据类型错误 */ - BIND_DATA_TYPE_UNKNOWN, /* struct lua_binding_data格式中数据类型无法识别, 或在该功能中操作了不支持的数据类型 */ - /* 通用返回值 */ - PARAM_ERR = -1, /* 传入参数错误, 可能是指针为空或类型不符合 */ - SUCCESS = 0, /* 运行成功 */ -}; - -/* ***** ***** ***** ***** ***** ***** */ -/* 需要注册至lua中的函数 */ -typedef int (*lua_cbind_func)(struct lua_state *state); -struct lua_bind_function_spec -{ - lua_cbind_func function; /* 注册函数原型 */ - char *func_name; /* 注册至lua中的函数名称 */ - char *space_name; /* 注册至lua中的命名空间名称 */ -}; -int lua_cbinding_function(struct lua_state *state, struct lua_bind_function_spec bind_function[], size_t bind_func_num); - -extern const char *context_magic_code; -struct lua_context -{ - const char *magic_code; - struct lua_state *state; - int lua_context_ref_id; -}; -struct lua_context *lua_context_new(struct lua_state *state); -void lua_context_free(struct lua_context *context); -void lua_context_push_stack(struct lua_context *context); - -enum DATATYPE -{ - DATATYPE_BEGIN = 0, - DATATYPE_NIL, /* nil类型 */ - DATATYPE_BOOL, /* bool类型 */ - DATATYPE_INT, /* int类型 */ - DATATYPE_NUM, /* double类型 */ - DATATYPE_STRING, /* 字符串类型 */ - /* 以下类型不能用于全局变量注册 */ - DATATYPE_TABLE, /* table类型 */ - DATATYPE_LUA_TABLE, /* 此类型用于在lua之间翻译传递数据 */ - DATATYPE_POINTER, /* 指针类型 */ - DATATYPE_CONTEXT, /* context上下文类型 */ - DATATYPE_FUNCTION, /* 函数类型 */ - DATATYPE_END -}; - -/* 需要注册至lua状态机中的数据 */ -struct lua_bind_data_spec -{ - enum DATATYPE data_type; /* 注册的数据类型 */ - char *data_value; /* 注册数数据值 */ - char *data_name; /* 注册的数据名称 */ - char *space_name; /* 注册至lua中的命名空间名称 */ -}; -int lua_cbinding_data(struct lua_state *state, struct lua_bind_data_spec bind_data[], size_t bind_data_num); - -struct lua_cdata; -struct lua_cnode; -struct lua_ctable; - -struct lua_cdata -{ - enum DATATYPE type; - size_t data_len; /* 只有在类型为function时使用此标识 */ - union - { - int bool; - int integer; - double number; - char *string; - - int table; - void *pointer; - struct lua_context *context; - void *function; - struct lua_ctable *ctable; - }; -}; - -struct lua_cnode -{ - char *node_string_key; - int node_integer_key; - struct lua_cdata *node_data; -}; - -struct lua_ctable -{ - size_t array_size; - size_t node_size; - struct lua_cdata **array_data; - struct lua_cnode **node_data; -}; - -struct lua_cdata *lua_cdata_new(void); -void lua_cdata_free(struct lua_cdata *cdata); -int lua_cdata_push_stack(struct lua_state *state, struct lua_cdata *cdata); -int lua_cdata_pop_stack(struct lua_state *state, struct lua_cdata *cdata); -struct lua_ctable *lua_ctable_new(void); -void lua_ctable_free(struct lua_ctable *ctable); -int lua_ctable_push_stack(struct lua_state *state, struct lua_ctable *ctable); -int lua_ctable_pop_stack(struct lua_state *state, struct lua_ctable *ctable); -struct lua_cnode *lua_cnode_new(void); -void lua_cnode_free(struct lua_cnode *cnode); - -/* ***** ***** ***** ***** ***** ***** */ -int lua_chunk_execute(struct lua_state *state, int fn_ref_id, struct lua_cdata param[], size_t param_num, struct lua_cdata returnvalue[], size_t r_num, char *errlog, size_t err_len); - -/* ***** ***** ***** ***** ***** ***** */ -struct lua_load_script -{ - int lua_load_fn_ref_id; - int lua_unload_fn_ref_id; - int lua_script_env_ref_id; -}; - -struct lua_session_plugin_env -{ - struct lua_session_plugin_env *next; - struct lua_plugin_manage *plugin_manage; - int session_plugin_id; - int lua_ctx_new_fn_ref_id; - int lua_ctx_free_fn_ref_id; - int lua_plug_env_ref_id; -}; - -struct lua_packet_plugin_env -{ - struct lua_packet_plugin_env *next; - struct lua_plugin_manage *plugin_manage; - int packet_plugin_id; - int lua_on_packet_fn_ref_id; - int lua_plug_env_ref_id; -}; - -struct lua_message_free_arg -{ - struct lua_message_free_arg *next; - struct lua_plugin_manage *plugin_manage; - int topic_id; - int lua_msg_free_fn_ref_id; - int lua_msg_free_arg_ref_id; -}; - -struct lua_on_message_fn -{ - int hash_on_use; - int topic_id; - int plugin_id; - int lua_on_msg_fn_ref_id; -}; - -#define HASH_MAX_NUM 1024 -int calc_on_message_func_hash_key(int topic_id, int plugin_id); -struct lua_on_message_fn *hash_on_msg_fn_insert(struct lua_on_message_fn msg_fn_hashlist[], int topic_id, int plugin_id); -struct lua_on_message_fn *hash_find_on_msg_fn(struct lua_on_message_fn msg_fn_hashlist[], int topic_id, int plugin_id); - -#define LUA_GLOBAL_THREAD_ID_KEY "__global_thread_id" -#define LUA_GLOBAL_STELLAR_POINTER "__global_stellar_pointer" -#define LUA_GLOBAL_PLUGIN_MANGE_POINTER "__global_plugin_managee_pointer" - -// int lua_state_get_thread_id(struct lua_state * state); -// struct stellar * lua_state_get_stellar(struct lua_state * state); -struct lua_plugin_manage *lua_state_get_plugin_manage(struct lua_state *state); - -struct lua_plugin_manage -{ - struct stellar *st; - - size_t state_num; - size_t load_script_num; - struct lua_state **state_array; - struct lua_load_script *load_script_array; - - struct lua_session_plugin_env *session_plugin_env_list; - struct lua_packet_plugin_env *packet_plugin_env_list; - struct lua_message_free_arg *message_free_arg_list; - - struct lua_on_message_fn on_session_message_hashlist[HASH_MAX_NUM]; - struct lua_on_message_fn on_packet_message_hashlist[HASH_MAX_NUM]; -}; - -#endif \ No newline at end of file