summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorniubinghui <[email protected]>2024-10-14 19:04:56 +0800
committerniubinghui <[email protected]>2024-10-14 19:04:56 +0800
commitbe165549d1dfe25a0c3badadf449aa48e4a349e6 (patch)
treeb7ac7977c160d4cd2a66373b0ffac24c0f5acc37
parent965403fbad1b32c762ad5a5f1226f8ff1534cb2f (diff)
【新增】完成新接口代码修改,通过编译未测试
-rw-r--r--include/lua_module_manage.h16
-rw-r--r--src/Makefile14
-rw-r--r--src/lua_binding_cfunc.c116
-rw-r--r--src/lua_binding_cfunc.h17
-rw-r--r--src/lua_binding_function.c863
-rw-r--r--src/lua_binding_function.h85
-rw-r--r--src/lua_module_manage.c137
-rw-r--r--src/lua_module_manage_internal.c862
-rw-r--r--src/lua_module_manage_internal.h231
-rw-r--r--src/lua_plugin_cfunc.c201
-rw-r--r--src/lua_plugin_manage.c931
-rw-r--r--src/lua_plugin_manage_internal.h217
12 files changed, 1766 insertions, 1924 deletions
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(&param[0], DATATYPE_CONTEXT, msg, 0);
+ else
+ lua_cdata_data_set(&param[0], DATATYPE_POINTER, msg, 0);
+ lua_cdata_data_set(&param[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(&param[0], DATATYPE_INT, NULL, topic_id);
+ if (lua_context_check_if_context(msg))
+ lua_cdata_data_set(&param[1], DATATYPE_CONTEXT, msg, 0);
+ else
+ lua_cdata_data_set(&param[1], DATATYPE_POINTER, msg, 0);
+ lua_cdata_data_set(&param[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(&param[0], DATATYPE_INT, NULL, topic_id);
+ lua_cdata_data_set(&param[1], DATATYPE_CONTEXT, msg, 0);
+ lua_cdata_data_set(&param[2], DATATYPE_TABLE, 0, dis_arg->lua_arg_ref_id);
+ lua_cdata_data_set(&param[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(&param[0], DATATYPE_INT, NULL, stage);
+ lua_cdata_data_set(&param[1], DATATYPE_POINTER, pkt, 0);
+ lua_cdata_data_set(&param[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(&param[0], DATATYPE_POINTER, sess, 0);
+ lua_cdata_data_set(&param[1], DATATYPE_POINTER, pkt, 0);
+ lua_cdata_data_set(&param[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(&param[0], DATATYPE_POINTER, sess, 0);
+ lua_cdata_data_set(&param[1], DATATYPE_BUFF, (void *)tcp_payload, (int)tcp_payload_len);
+ lua_cdata_data_set(&param[2], DATATYPE_INT, NULL, (int)tcp_payload_len);
+ lua_cdata_data_set(&param[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,671 +1,502 @@
+#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 <stdlib.h>
#include <string.h>
-
+#include <utlist.h>
#include <lua.h>
+#include <lualib.h>
#include <lauxlib.h>
-#include <utlist.h>
-#include "lua_binding_function.h"
+#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; \
+ }
-/* ***** ***** ***** ***** ***** ***** */
-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;
+#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; \
}
- 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)
+int lua_mq_schema_get_topic_id(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 1)
+ if (lua_gettop(L) != 2 || lua_type(L, -1) != LUA_TSTRING || lua_type(L, -2) != LUA_TLIGHTUSERDATA)
{
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;
+ char *topic_name = strdup(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_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);
+ int topic_id = mq_schema_get_topic_id(s, (const char *)topic_name);
+
+ if (topic_name)
+ FREE(topic_name);
+ lua_pushinteger(L, topic_id);
return 1;
}
-*/
-/* ***** ***** ***** ***** ***** ***** */
-int lua_session_plugin_regist(struct lua_state *state)
+int lua_mq_schema_create_topic(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 4 || lua_type(L, -4) != LUA_TLIGHTUSERDATA)
+ if (lua_gettop(L) != 6 || lua_type(L, -5) != LUA_TSTRING || lua_type(L, -6) != LUA_TLIGHTUSERDATA)
{
lua_settop(L, 0);
return 0;
}
- /* 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;
+ int free_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
+ int free_cb_fn_ref_id = -1;
if (lua_type(L, -1) == LUA_TFUNCTION)
- ctx_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 ctx_new_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)
- ctx_new_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
+ on_dispatch_cb_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
else
lua_pop(L, 1);
-
- /* stack -4 */
- struct stellar *st = (struct stellar *)lua_topointer(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_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);
+ 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;
}
-int lua_packet_plugin_regist(struct lua_state *state)
+int lua_mq_schema_update_topic(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 4 || lua_type(L, -4) != LUA_TLIGHTUSERDATA)
+ 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 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;
+ int free_arg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
+ int free_cb_fn_ref_id = -1;
if (lua_type(L, -1) == LUA_TFUNCTION)
- on_packet_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 ip_protocol = lua_tointeger(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);
+ int topic_id = lua_tointeger(L, -1);
lua_pop(L, 1);
-
- /* stack -4 */
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
+ struct mq_schema *s = (struct mq_schema *)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);
+ 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)
+ {
+ 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
+ {
+ 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_pushinteger(L, update_ret);
return 1;
}
-/* ***** ***** ***** ***** ***** ***** */
-int lua_session_get_type(struct lua_state *state)
+int lua_mq_shcema_destory_topic(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 1 || lua_type(L, -1) != LUA_TLIGHTUSERDATA)
+ if (lua_gettop(L) != 2 || lua_type(L, -1) != LUA_TNUMBER || lua_type(L, -2) != LUA_TLIGHTUSERDATA)
{
lua_settop(L, 0);
return 0;
}
- struct session *sess = (struct session *)lua_topointer(L, -1);
+ 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);
- if (!sess)
- return 0;
- lua_pushinteger(L, (int)session_get_type(sess));
+ int destory_ret = mq_schema_destroy_topic(s, topic_id);
+
+ lua_pushinteger(L, destory_ret);
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)
+int lua_mq_schema_subscribe(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 4 || lua_type(L, -3) != LUA_TSTRING || lua_type(L, -4) != LUA_TLIGHTUSERDATA)
+ if (lua_gettop(L) != 4 || lua_type(L, -2) != LUA_TFUNCTION || 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));
+ 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);
-
- /* stack -4 */
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
+ struct mq_schema *s = (struct mq_schema *)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_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)
{
- 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);
+ 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
{
- if (new_message_free_arg)
- free(new_message_free_arg);
- return 0;
+ 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, topic_id);
+ lua_pushinteger(L, subscribe_ret);
return 1;
}
-static int lua_plugin_manage_msg_mq_get_topic_id(struct lua_state *state, int type)
+int lua_mq_runtime_publish_message(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)
+ if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TNUMBER || lua_type(L, -3) != LUA_TLIGHTUSERDATA)
{
lua_settop(L, 0);
return 0;
}
- char *topic_name = strdup(lua_tostring(L, -1));
+ int msg_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
+ int topic_id = lua_tointeger(L, -1);
lua_pop(L, 1);
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
+ struct mq_runtime *rt = (struct mq_runtime *)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);
- if (topic_name)
- free(topic_name);
+ struct lua_context *new_context = lua_context_new_with_ref_id(state, msg_ref_id);
- lua_pushinteger(L, topic_id);
+ int publish_ret = mq_runtime_publish_message(rt, topic_id, new_context);
+ if (publish_ret)
+ {
+ lua_context_free(new_context);
+ }
+ lua_pushinteger(L, publish_ret);
return 1;
}
-static int lua_plugin_manage_msg_mq_update_topic(struct lua_state *state, int type)
-{
- 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;
-
- /* 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);
+LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_module_manager_get_thread_id,
+ struct stellar_module_manager,
+ stellar_module_manager_get_thread_id)
- /* stack -3 */
- int topic_id = lua_tointeger(L, -1);
- lua_pop(L, 1);
+LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_module_manager_get_max_thread_num,
+ struct stellar_module_manager,
+ stellar_module_manager_get_max_thread_num)
- /* stack -4 */
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
- lua_settop(L, 0);
+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)
- 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;
-}
+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)
-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;
+LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_module_manager_get_logger,
+ struct stellar_module_manager,
+ struct logger,
+ stellar_module_manager_get_logger)
- int topic_id = lua_tointeger(L, -1);
- lua_pop(L, 1);
+LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_packet_get_direction,
+ const struct packet,
+ packet_get_direction)
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
- lua_settop(L, 0);
+LUA_BINDING_FUNCTION_GET_VALUE_POINTER(lua_packet_get_payload,
+ const struct packet,
+ const char,
+ packet_get_payload)
- 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;
-}
+LUA_BINDING_FUNCTION_GET_VALUE_INT(lua_packet_get_payload_len,
+ const struct packet,
+ packet_get_payload_len)
-static int lua_plugin_manage_msg_mq_subscribe_topic(struct lua_state *state, int type)
+int lua_packet_manager_subscribe(struct lua_state *state)
{
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;
- if (lua_type(L, -1) == LUA_TFUNCTION)
- on_message_fn_ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
- else
- lua_pop(L, 1);
+ 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;
+ }
- int topic_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);
- struct stellar *st = (struct stellar *)lua_topointer(L, -1);
+ struct packet_manager *pkt_mgr = (struct packet_manager *)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_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)
{
- on_message->lua_on_msg_fn_ref_id = on_message_fn_ref_id;
+ 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);
}
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_on_packet_arg->lua_mod_mgr = lua_mod_mgr;
+ LL_APPEND(lua_mod_mgr->on_packet_stage_list, new_on_packet_arg);
}
- lua_settop(L, 0);
- lua_pushboolean(L, 1);
- return 1;
-err:
- lua_settop(L, 0);
- lua_pushboolean(L, 0);
+ lua_pushinteger(L, subscribe_ret);
return 1;
}
-static int lua_plugin_manage_msg_mq_publish_message(struct lua_state *state, int type)
+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)
- goto err;
-
- 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);
+ if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -3) != LUA_TLIGHTUSERDATA)
+ {
+ lua_settop(L, 0);
+ return 0;
+ }
- void *p = (void *)lua_topointer(L, -1);
+ 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_context *new_context = lua_context_new(state);
- new_context->lua_context_ref_id = 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)
+ 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)
{
- luaL_unref(L, LUA_REGISTRYINDEX, new_context->lua_context_ref_id);
- free(new_context);
- goto err;
+ 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)
+ {
+ 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;
+ }
}
- lua_pushboolean(L, 1);
- return 1;
-err:
- lua_settop(L, 0);
- lua_pushboolean(L, 0);
+ lua_pushinteger(L, subscribe_ret);
return 1;
}
-/* ***** ***** ***** ***** ***** ***** */
-int lua_packet_mq_create_topic(struct lua_state *state)
+int lua_session_manager_subscribe_tcp(struct lua_state *state)
{
- return lua_plugin_manage_msg_mq_create_topic(state, MQ_TYPE_PACKET);
+ return lua_session_manager_subscribe(state, sub_type_tcp);
}
-int lua_packet_mq_get_topic_id(struct lua_state *state)
+int lua_session_manager_subscribe_udp(struct lua_state *state)
{
- return lua_plugin_manage_msg_mq_get_topic_id(state, MQ_TYPE_PACKET);
+ return lua_session_manager_subscribe(state, sub_type_udp);
}
-int lua_packet_mq_update_topic(struct lua_state *state)
+int lua_session_manager_subscribe_control_packet(struct lua_state *state)
{
- return lua_plugin_manage_msg_mq_update_topic(state, MQ_TYPE_PACKET);
+ return lua_session_manager_subscribe(state, sub_type_control_pkt);
}
-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)
+int lua_session_manager_subscribe_tcp_stream(struct lua_state *state)
{
lua_State *L = (lua_State *)state;
- if (lua_gettop(L) != 3)
- 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_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);
+ if (lua_gettop(L) != 3 || lua_type(L, -2) != LUA_TFUNCTION || lua_type(L, -4) != LUA_TLIGHTUSERDATA)
+ {
+ lua_settop(L, 0);
+ return 0;
+ }
- struct session *sess = (struct session *)lua_topointer(L, -1);
+ 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);
- /* 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_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)
{
- return -1;
- }
- int i, j;
- unsigned char num = inlen % 3;
- if (outdata != NULL)
- {
- // 编码,3个字节一组,若数据总长度不是3的倍数,则跳过最后的 num 个字节数据
- for (i = 0, j = 0; i < inlen - num; i += 3, j += 4)
- {
- 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];
- }
- // 继续处理最后的 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 (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);
}
- if (outlen != NULL)
+ else
{
- *outlen = (inlen + (num == 0 ? 0 : 3 - num)) * 4 / 3;
+ 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);
}
- return 0;
+ lua_pushinteger(L, subscribe_ret);
+ return 1;
}
-
-int lua_session_get0_current_payload(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))
- {
- lua_pushstring(L, payload_base64);
- lua_pushinteger(L, (lua_Integer)payload_len);
- if (payload_base64)
- free(payload_base64);
- return 2;
- }
- if (payload_base64)
- free(payload_base64);
-err:
- lua_settop(L, 0);
- lua_pushstring(L, NULL);
- lua_pushboolean(L, 0);
- return 2;
-#endif
-} \ No newline at end of file
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"
-
-#include "lua_plugin_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_session_plugin_regist(struct lua_state *state);
-int lua_packet_plugin_regist(struct lua_state *state);
-
-/* struct session结构相关的函数 */
-int lua_session_get_type(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);
-
-/* 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);
-
-/* session相关其他函数 */
-int lua_session_get0_current_payload(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
+#ifndef LUA_MODULE_MANAGE_BINDING_FUNCTION_H
+#define LUA_MODULE_MANAGE_BINDING_FUNCTION_H
+
+#include "lua_module_manage_internal.h"
+
+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_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);
+
+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);
+
+int lua_packet_manager_subscribe(struct lua_state *state);
+
+int lua_session_get0_current_packet(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);
+
+#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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#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 <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <toml.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+/* ***** ***** ***** ***** ***** ***** */
+/* 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, &param[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 <stddef.h>
+#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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <utlist.h>
-
-#include <lauxlib.h>
-#include <lualib.h>
-
-#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, &param[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, &param, 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 <stddef.h>
-#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