【新增】实现数据管理能力
This commit is contained in:
33
src/Makefile
Normal file
33
src/Makefile
Normal file
@@ -0,0 +1,33 @@
|
||||
TOPDIR = ./..
|
||||
CC=gcc
|
||||
MAKE=make
|
||||
TARGET=libluaplugin.so
|
||||
|
||||
TEST_FLAG = -DLUAPLUGIN_BASIC_UNITTEST
|
||||
|
||||
SRC := lua_plugin_binding.c \
|
||||
lua_plugin_data.c \
|
||||
lua_plugin_cfunc.c \
|
||||
lua_plugin_manage.c
|
||||
|
||||
OBJECTS := lua_plugin_binding.o \
|
||||
lua_plugin_data.o \
|
||||
lua_plugin_cfunc.o \
|
||||
lua_plugin_manage.o
|
||||
|
||||
INCLUDE = -I$(TOPDIR)/dependence/include -I$(TOPDIR)/include
|
||||
CFLAGS = -g -Wextra -Wall -O0 -fPIC
|
||||
# CFLAGS += -pedantic -fsanitize=address
|
||||
LDLIBS = -L$(TOPDIR)/dependence/lib -llua -ltoml -ldl -lm
|
||||
|
||||
all:$(OBJECTS)
|
||||
$(CC) $(CFLAGS) -shared -o $(TARGET) $(OBJECTS) $(LDLIBS)
|
||||
mkdir -p $(TOPDIR)/output/libs
|
||||
cp -f $(TARGET) $(TOPDIR)/output/libs
|
||||
|
||||
$(OBJECTS):$(SRC)
|
||||
$(CC) $(TEST_FLAG) $(INCLUDE) $(CFLAGS) $(SRC) -c $^
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJECTS) $(TARGET)
|
||||
rm -rf $(TOPDIR)/output/libs/$(TARGET)
|
||||
@@ -506,7 +506,7 @@ int lua_plugin_manage_session_regist(lua_State *state)
|
||||
return 0;
|
||||
}
|
||||
lua_pop(state, 1);
|
||||
#if 0
|
||||
|
||||
/* 取出处理第一个参数 */
|
||||
struct stellar * st = (struct stellar *)lua_topointer(state, -1);
|
||||
if ( !st ) {
|
||||
@@ -522,8 +522,8 @@ int lua_plugin_manage_session_regist(lua_State *state)
|
||||
memset(&session_plugin, 0, sizeof(session_plugin));
|
||||
session_plugin_instance_init(&session_plugin, state, plugin_id, ctx_new_id, ctx_free_id);
|
||||
|
||||
utarray_push_back(plugin_env->lua_plugin_env_plugin_array, &session_plugin);
|
||||
utarray_push_back(plugin_env->plugin_env_plugin_array, &session_plugin);
|
||||
lua_pushinteger(state, plugin_id);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
115
src/lua_plugin_cfunc.c
Normal file
115
src/lua_plugin_cfunc.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*************************************************************************
|
||||
> File Name: lua_plugin_cfunc.c
|
||||
> Author:
|
||||
> Created Time: 2024-08
|
||||
> Encoding : UTF-8
|
||||
************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
* version
|
||||
* [ v0.1 ]
|
||||
* 08-06
|
||||
* 1. 实现函数
|
||||
* void *lpm_ctx_new_func;
|
||||
* void lpm_ctx_free_func;
|
||||
************************************************************************/
|
||||
#include "lua_plugin_manage_internal.h"
|
||||
|
||||
/*
|
||||
* Function: lpm_ctx_new_func
|
||||
* Input: | struct session * | sess | 会话信息
|
||||
* | void * | plugin_env | 插件运行环境
|
||||
* Output:
|
||||
* Return: | NULL | 运行函数错误
|
||||
* | pointer | 运行插件上的ctx_new函数成功, 返回context
|
||||
* Description: 与C插件管理器保持一致的ctx_new_func
|
||||
*/
|
||||
void *lpm_ctx_new_func(
|
||||
struct session *sess,
|
||||
void *plugin_env)
|
||||
{
|
||||
if (__glibc_unlikely(!sess || !plugin_env))
|
||||
return NULL;
|
||||
struct lua_plugin_env *env = (struct lua_plugin_env *)plugin_env;
|
||||
|
||||
/* 获取插件ID并找到该插件 */
|
||||
// int plugin_id = session_get_pluginid(sess);
|
||||
int plugin_id = 1;
|
||||
struct lua_session_plugin *plugin = NULL;
|
||||
while ((plugin = utarray_next(env->plugin_env_plugin_array, plugin)))
|
||||
{
|
||||
if (plugin->plugin_id == plugin_id)
|
||||
break;
|
||||
}
|
||||
if (!plugin || plugin->plugin_id != plugin_id)
|
||||
/* 未找到该插件 */
|
||||
return NULL;
|
||||
|
||||
struct lua_context *new_context = lua_context_new(env->plugin_env_state);
|
||||
if (__glibc_unlikely(!new_context))
|
||||
/* 创建新的context失败 */
|
||||
return NULL;
|
||||
|
||||
struct lua_cdata param[3] = {0};
|
||||
param[0].cdata_type = DATATYPE_POINTER;
|
||||
param[0].cdata_pointer = sess;
|
||||
param[1].cdata_type = DATATYPE_TABLE;
|
||||
param[1].cdata_table = env->plugin_env_ref_id;
|
||||
param[2].cdata_type = DATATYPE_CONTEXT;
|
||||
param[2].cdata_context = new_context;
|
||||
|
||||
if (script_execute(&plugin->plugin_ctx_new_script, 3, param, 0, NULL))
|
||||
{
|
||||
/* 脚本执行失败 */
|
||||
free(new_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *)new_context;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lpm_ctx_free_func
|
||||
* Input: | struct session * | sess | 会话信息
|
||||
* | void * | sess_ctx | 会话中的私有数据
|
||||
* | void * | plugin_env | 插件运行环境
|
||||
* Output:
|
||||
* Return:
|
||||
* Description: 与C插件管理器保持一致的ctx_free_func
|
||||
*/
|
||||
void lpm_ctx_free_func(
|
||||
struct session *sess,
|
||||
void *sess_ctx,
|
||||
void *plugin_env)
|
||||
{
|
||||
if (__glibc_unlikely(!sess || !sess_ctx || !plugin_env))
|
||||
return;
|
||||
struct lua_context *context = (struct lua_context *)sess_ctx;
|
||||
struct lua_plugin_env *env = (struct lua_plugin_env *)plugin_env;
|
||||
|
||||
/* 获取插件ID并找到该插件 */
|
||||
// int plugin_id = session_get_pluginid(sess);
|
||||
int plugin_id = 1;
|
||||
struct lua_session_plugin *plugin = NULL;
|
||||
while ((plugin = utarray_next(env->plugin_env_plugin_array, plugin)))
|
||||
{
|
||||
if (plugin->plugin_id == plugin_id)
|
||||
break;
|
||||
}
|
||||
if (!plugin || plugin->plugin_id != plugin_id)
|
||||
/* 未找到该插件 */
|
||||
return;
|
||||
|
||||
struct lua_cdata param[3] = {0};
|
||||
param[0].cdata_type = DATATYPE_POINTER;
|
||||
param[0].cdata_pointer = sess;
|
||||
param[1].cdata_type = DATATYPE_CONTEXT;
|
||||
param[1].cdata_context = context;
|
||||
param[2].cdata_type = DATATYPE_TABLE;
|
||||
param[2].cdata_table = env->plugin_env_ref_id;
|
||||
|
||||
script_execute(&plugin->plugin_ctx_free_script, 3, param, 0, NULL);
|
||||
lua_context_free(context);
|
||||
|
||||
return;
|
||||
}
|
||||
210
src/lua_plugin_data.c
Normal file
210
src/lua_plugin_data.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*************************************************************************
|
||||
> File Name: lua_plugin_data.c
|
||||
> Author:
|
||||
> Created Time: 2024-08
|
||||
> Encoding : UTF-8
|
||||
************************************************************************/
|
||||
|
||||
/*************************************************************************
|
||||
* version
|
||||
* [ v0.1 ]
|
||||
* 08-06
|
||||
* 1. 实现函数
|
||||
* int lua_cdata_push_stack;
|
||||
* int lua_cdata_pop_stack;
|
||||
* void lua_cdata_destory;
|
||||
* struct lua_context * lua_context_new;
|
||||
* int lua_context_push_stack;
|
||||
* void lua_context_free;
|
||||
************************************************************************/
|
||||
#include "lua_plugin_manage_internal.h"
|
||||
|
||||
/*
|
||||
* Function: lua_cdata_push_stack
|
||||
* Input: | lua_State * | state | 入栈数据使用的状态机
|
||||
* | struct lua_cdata * | cdata | 需要入栈的数据
|
||||
* Output:
|
||||
* Return: | -1 | 参数错误
|
||||
* | 1 | 入栈数据类型有误
|
||||
* | 0 | 入栈成功
|
||||
* Description: 将一个数据元素入栈
|
||||
*/
|
||||
int lua_cdata_push_stack(
|
||||
lua_State *state,
|
||||
struct lua_cdata *cdata)
|
||||
{
|
||||
if (__glibc_unlikely(!state || !cdata))
|
||||
return -1;
|
||||
|
||||
switch (cdata->cdata_type)
|
||||
{
|
||||
case DATATYPE_NIL:
|
||||
lua_pushnil(state);
|
||||
return 0;
|
||||
case DATATYPE_BOOL:
|
||||
lua_pushboolean(state, cdata->cdata_bool);
|
||||
return 0;
|
||||
case DATATYPE_INT:
|
||||
lua_pushinteger(state, cdata->cdata_int);
|
||||
return 0;
|
||||
case DATATYPE_NUM:
|
||||
lua_pushnumber(state, cdata->cdata_num);
|
||||
return 0;
|
||||
case DATATYPE_STRING:
|
||||
lua_pushstring(state, cdata->cdata_string);
|
||||
return 0;
|
||||
case DATATYPE_TABLE:
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, cdata->cdata_table);
|
||||
return 0;
|
||||
case DATATYPE_POINTER:
|
||||
lua_pushlightuserdata(state, (void *)cdata->cdata_pointer);
|
||||
return 0;
|
||||
case DATATYPE_CONTEXT:
|
||||
lua_context_push_stack(cdata->cdata_context);
|
||||
return 0;
|
||||
default:
|
||||
LOGERROR("can't recorgnize data type %d", cdata->cdata_type);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lua_cdata_pop_stack
|
||||
* Input: | lua_State * | state | 出栈数据使用的状态机
|
||||
* | struct lua_cdata * | cdata | 保存出栈的元素
|
||||
* Output:
|
||||
* Return: | -1 | 参数错误
|
||||
* | -2 | 出栈数据类型有误
|
||||
* | 0 | 出栈成功
|
||||
* Description: 将一个数据元素出栈, 出栈过程中无法出栈context与table类型
|
||||
* TODO: 扩展类型, 支持更多数据类型
|
||||
*/
|
||||
int lua_cdata_pop_stack(
|
||||
lua_State *state,
|
||||
struct lua_cdata *cdata)
|
||||
{
|
||||
if (__glibc_unlikely(!state || !cdata))
|
||||
return -1;
|
||||
if (!lua_gettop(state))
|
||||
return 0;
|
||||
|
||||
switch (lua_type(state, -1))
|
||||
{
|
||||
case LUA_TNIL:
|
||||
cdata->cdata_type = DATATYPE_NIL;
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
cdata->cdata_type = DATATYPE_BOOL;
|
||||
cdata->cdata_bool = lua_toboolean(state, -1);
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
cdata->cdata_type = DATATYPE_NUM;
|
||||
cdata->cdata_num = lua_tonumber(state, -1);
|
||||
int try_int = (int)cdata->cdata_num;
|
||||
if ((double)try_int == cdata->cdata_num)
|
||||
{
|
||||
cdata->cdata_type = DATATYPE_INT;
|
||||
cdata->cdata_int = lua_tointeger(state, -1);
|
||||
}
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
cdata->cdata_type = DATATYPE_STRING;
|
||||
cdata->cdata_string = (char *)strdup(lua_tostring(state, -1));
|
||||
break;
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
cdata->cdata_type = DATATYPE_POINTER;
|
||||
cdata->cdata_pointer = (void *)lua_topointer(state, -1);
|
||||
break;
|
||||
default:
|
||||
/* 其他数据类型之后处理 */
|
||||
LOGERROR("other lua type can't pop out, %d", lua_type(state, -1));
|
||||
return -2;
|
||||
}
|
||||
|
||||
lua_pop(state, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lua_cdata_destory
|
||||
* Input: | struct lua_cdata * | cdata | 待销毁的data结构
|
||||
* Output:
|
||||
* Return:
|
||||
* Description: 销毁是一个data结构, 释放内部占用内存
|
||||
* 目前该函数仅数据类型为string的时候需要调用一次
|
||||
*/
|
||||
void lua_cdata_destory(struct lua_cdata *cdata)
|
||||
{
|
||||
if (__glibc_unlikely(!cdata))
|
||||
return;
|
||||
if (cdata->cdata_type == DATATYPE_STRING && cdata->cdata_string)
|
||||
free(cdata->cdata_string);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lua_context_new
|
||||
* Input: | lua_State * | state | 创建context使用的状态机
|
||||
* Output:
|
||||
* Return: | NULL | 创建失败
|
||||
* | pointer | 创建成功, 返回创建的context指针
|
||||
* Description: 创建一个context结构, 由于context结构使用需要在状态机中生成引用值, 单独重写一个new函数
|
||||
*/
|
||||
struct lua_context *lua_context_new(lua_State *state)
|
||||
{
|
||||
if (__glibc_unlikely(!state))
|
||||
return NULL;
|
||||
|
||||
lua_newtable(state);
|
||||
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||
lua_settop(state, 0);
|
||||
if (ref_id == LUA_REFNIL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context));
|
||||
if (__glibc_unlikely(!new_context))
|
||||
{
|
||||
luaL_unref(state, LUA_REGISTRYINDEX, ref_id);
|
||||
return NULL;
|
||||
}
|
||||
new_context->context_state = state;
|
||||
new_context->context_ref_id = ref_id;
|
||||
return new_context;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lua_context_push_stack
|
||||
* Input: | struct lua_context * | context | 待入栈的context结构
|
||||
* Output:
|
||||
* Return: | 0 | 入栈成功
|
||||
* | -1 | 参数错误
|
||||
* Description: 将一个context入栈, 实际入栈流程与table一致
|
||||
*/
|
||||
int lua_context_push_stack(struct lua_context *context)
|
||||
{
|
||||
if (luai_unlikely(!context))
|
||||
return -1;
|
||||
|
||||
lua_rawgeti(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: lua_context_free
|
||||
* Input: | struct lua_context * | context | 释放一个context
|
||||
* Output:
|
||||
* Return:
|
||||
* Description: 释放一个context
|
||||
*/
|
||||
void lua_context_free(struct lua_context *context)
|
||||
{
|
||||
if (__glibc_unlikely(!context))
|
||||
return;
|
||||
luaL_unref(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
||||
free(context);
|
||||
return;
|
||||
}
|
||||
@@ -25,6 +25,10 @@
|
||||
* int thread_state_instance_load;
|
||||
* int lua_plugin_manage_config_load;
|
||||
* int lua_plugin_manage_thread_load;
|
||||
*
|
||||
* 08-06
|
||||
* 1. 实现函数
|
||||
* int script_execute;
|
||||
************************************************************************/
|
||||
#include "lua_plugin_manage_internal.h"
|
||||
#include "lpm_log.h"
|
||||
@@ -55,10 +59,10 @@ void specific_instance_copy(void *dst, const void *src)
|
||||
struct lua_config_specific *src_spec = (struct lua_config_specific *)src;
|
||||
if (__glibc_unlikely(!dst_spec || !src_spec))
|
||||
return;
|
||||
dst_spec->lua_config_specific_file = strdup(src_spec->lua_config_specific_file);
|
||||
// dst_spec->lua_config_specific_name = strdup(src_spec->lua_config_specific_name);
|
||||
dst_spec->lua_config_specific_load_func = strdup(src_spec->lua_config_specific_load_func);
|
||||
dst_spec->lua_config_specific_unload_func = strdup(src_spec->lua_config_specific_unload_func);
|
||||
dst_spec->config_specific_file = strdup(src_spec->config_specific_file);
|
||||
// dst_spec->config_specific_name = strdup(src_spec->config_specific_name);
|
||||
dst_spec->config_specific_load_func = strdup(src_spec->config_specific_load_func);
|
||||
dst_spec->config_specific_unload_func = strdup(src_spec->config_specific_unload_func);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,14 +78,14 @@ void specific_instance_destory(void *elt)
|
||||
struct lua_config_specific *element = (struct lua_config_specific *)elt;
|
||||
if (!element)
|
||||
return;
|
||||
if (element->lua_config_specific_file)
|
||||
free(element->lua_config_specific_file);
|
||||
// if (element->lua_config_specific_name)
|
||||
// free(element->lua_config_specific_name);
|
||||
if (element->lua_config_specific_load_func)
|
||||
free(element->lua_config_specific_load_func);
|
||||
if (element->lua_config_specific_unload_func)
|
||||
free(element->lua_config_specific_unload_func);
|
||||
if (element->config_specific_file)
|
||||
free(element->config_specific_file);
|
||||
// if (element->config_specific_name)
|
||||
// free(element->config_specific_name);
|
||||
if (element->config_specific_load_func)
|
||||
free(element->config_specific_load_func);
|
||||
if (element->config_specific_unload_func)
|
||||
free(element->config_specific_unload_func);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -195,16 +199,95 @@ void script_instance_clean(struct lua_script *script)
|
||||
}
|
||||
|
||||
/*
|
||||
* Function:
|
||||
* Input:
|
||||
* Function: script_execute
|
||||
* Input: | struct lua_script * | script | 需要执行的lua脚本
|
||||
* | int | pcount | 传入的参数个数
|
||||
* | struct lua_cdata * | param | 传入的参数值
|
||||
* | int | rmaxcount | 最大可接收的返回值个数
|
||||
* | struct lua_cdata * | rvalue | 接收返回值的data结构
|
||||
* Output:
|
||||
* Return:
|
||||
* Description:
|
||||
* Return: | 0 | 脚本执行成功
|
||||
* | -1 | 参数错误
|
||||
* | -2 | 无法获取脚本调用的lua函数
|
||||
* | -3 | 参数无法入栈
|
||||
* | -4 | 函数执行过程中出错
|
||||
* | -5 | 返回值出栈过程中数量过多
|
||||
* | -6 | 返回值出栈失败
|
||||
* Description: 调用并执行一个lua脚本
|
||||
*/
|
||||
int script_execute(struct lua_script *script)
|
||||
int script_execute(
|
||||
struct lua_script *script,
|
||||
int pcount,
|
||||
struct lua_cdata * param,
|
||||
int rmaxcount,
|
||||
struct lua_cdata * rvalue)
|
||||
{
|
||||
if (!script)
|
||||
return -1;
|
||||
if ( (pcount && !param) || (pcount < 0) )
|
||||
return -1;
|
||||
if ( (rmaxcount && !rvalue) || (rmaxcount < 0) )
|
||||
return -1;
|
||||
|
||||
lua_State * state = script->script_state;
|
||||
|
||||
/* 需要调用的函数入栈, 由于后续在读取参数个数的时候对栈操作较多, 需要先将函数入栈 */
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, script->script_ref_id);
|
||||
if (lua_gettop(state) == 0 || lua_type(state, -1) != LUA_TFUNCTION)
|
||||
{
|
||||
lua_settop(state, 0);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* 参数入栈 */
|
||||
for (int i = 0; i < pcount; ++i) {
|
||||
if ( lua_cdata_push_stack(state, ¶m[i]) ) {
|
||||
lua_settop(state, 0);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
/* 执行该脚本并记录执行时间 */
|
||||
clock_t start_time, end_time;
|
||||
start_time = clock();
|
||||
/* 调用该脚本 or 代码片段 */
|
||||
if (lua_pcall(state, pcount, LUA_MULTRET, 0))
|
||||
{
|
||||
end_time = clock();
|
||||
LOGERROR("run script failed, mess is %s\n", lua_tostring(state, -1));
|
||||
/* 仅函数运行过程中出错记入出错记录, 由于参数错误等原因导致的错误不记录 */
|
||||
script->script_last_ms_start = start_time;
|
||||
script->script_last_ms_end = end_time;
|
||||
script->script_total_ms += (end_time - start_time);
|
||||
script->script_run_failed += 1;
|
||||
lua_settop(state, 0);
|
||||
return -4;
|
||||
}
|
||||
end_time = clock();
|
||||
|
||||
/* 返回值出栈 */
|
||||
if ( rmaxcount > 0 ) {
|
||||
/* 如果rmaxcount为0, 说明在期望中不准备接收返回值, 也不必处理 */
|
||||
int rcount = lua_gettop(state);
|
||||
if ( rcount > rmaxcount ) {
|
||||
lua_settop(state, 0);
|
||||
return -5;
|
||||
}
|
||||
for (int i = (rcount - 1); i >= 0; ++i) {
|
||||
if ( lua_cdata_pop_stack(state, &(rvalue[i])) ) {
|
||||
lua_settop(state, 0);
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 记录耗时等数据 */
|
||||
lua_settop(state, 0);
|
||||
script->script_last_ms_start = start_time;
|
||||
script->script_last_ms_end = end_time;
|
||||
script->script_total_ms += (end_time - start_time);
|
||||
script->script_run_success += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -274,32 +357,32 @@ int plugin_env_instance_init(
|
||||
return -1;
|
||||
|
||||
memset(plugin_env, 0, sizeof(struct lua_plugin_env));
|
||||
plugin_env->lua_plugin_env_state = state;
|
||||
plugin_env->lua_plugin_env_plugin_array = NULL;
|
||||
// plugin_env->lua_plugin_env_name = strdup(specific->lua_config_specific_name);
|
||||
plugin_env->plugin_env_state = state;
|
||||
plugin_env->plugin_env_plugin_array = NULL;
|
||||
// plugin_env->plugin_env_name = strdup(specific->config_specific_name);
|
||||
/* 从文件中加载load函数, 但此时不调用 */
|
||||
if (script_instance_init_byname(&plugin_env->lua_plugin_env_load_func,
|
||||
if (script_instance_init_byname(&plugin_env->plugin_env_load_func,
|
||||
state,
|
||||
specific->lua_config_specific_file,
|
||||
specific->lua_config_specific_load_func))
|
||||
specific->config_specific_file,
|
||||
specific->config_specific_load_func))
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
/* 从文件中加载unload函数 */
|
||||
if (script_instance_init_byname(&plugin_env->lua_plugin_env_unload_func,
|
||||
if (script_instance_init_byname(&plugin_env->plugin_env_unload_func,
|
||||
state,
|
||||
specific->lua_config_specific_file,
|
||||
specific->lua_config_specific_unload_func))
|
||||
specific->config_specific_file,
|
||||
specific->config_specific_unload_func))
|
||||
{
|
||||
script_instance_clean(&plugin_env->lua_plugin_env_load_func);
|
||||
script_instance_clean(&plugin_env->plugin_env_load_func);
|
||||
return -3;
|
||||
}
|
||||
/* 创建私有数据空间 */
|
||||
lua_newtable(plugin_env->lua_plugin_env_state);
|
||||
int ref_id = luaL_ref(plugin_env->lua_plugin_env_state, LUA_REGISTRYINDEX);
|
||||
lua_newtable(plugin_env->plugin_env_state);
|
||||
int ref_id = luaL_ref(plugin_env->plugin_env_state, LUA_REGISTRYINDEX);
|
||||
if (ref_id == LUA_REFNIL)
|
||||
return -4;
|
||||
plugin_env->lua_plugin_env_ref_id = ref_id;
|
||||
plugin_env->plugin_env_ref_id = ref_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -316,15 +399,24 @@ void plugin_env_instance_destory(void *elt)
|
||||
if (__glibc_unlikely(!elt))
|
||||
return;
|
||||
struct lua_plugin_env *plugin_env = (struct lua_plugin_env *)elt;
|
||||
|
||||
/* 调用自身unload函数 */
|
||||
struct lua_cdata param;
|
||||
param.cdata_type = DATATYPE_TABLE;
|
||||
param.cdata_table = plugin_env->plugin_env_ref_id;
|
||||
script_execute(&plugin_env->plugin_env_unload_func, 1, ¶m, 0, NULL);
|
||||
|
||||
/* 释放已经注册的插件 */
|
||||
if (plugin_env->lua_plugin_env_plugin_array)
|
||||
utarray_free(plugin_env->lua_plugin_env_plugin_array);
|
||||
if (plugin_env->plugin_env_plugin_array)
|
||||
utarray_free(plugin_env->plugin_env_plugin_array);
|
||||
|
||||
/* 释放插件的加载函数与卸载函数 */
|
||||
script_instance_clean(&plugin_env->lua_plugin_env_load_func);
|
||||
script_instance_clean(&plugin_env->lua_plugin_env_unload_func);
|
||||
script_instance_clean(&plugin_env->plugin_env_load_func);
|
||||
script_instance_clean(&plugin_env->plugin_env_unload_func);
|
||||
|
||||
/* 将lua中的私有环境数据取消引用 */
|
||||
if (plugin_env->lua_plugin_env_ref_id)
|
||||
luaL_unref(plugin_env->lua_plugin_env_state, LUA_REGISTRYINDEX, plugin_env->lua_plugin_env_ref_id);
|
||||
if (plugin_env->plugin_env_ref_id)
|
||||
luaL_unref(plugin_env->plugin_env_state, LUA_REGISTRYINDEX, plugin_env->plugin_env_ref_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -356,11 +448,11 @@ int thread_state_instance_init(
|
||||
lua_settop(new_state, 0);
|
||||
|
||||
memset(thread_state, 0, sizeof(struct lua_thread_state));
|
||||
thread_state->lua_thread_id = state_id;
|
||||
thread_state->lua_thread_plugin_count = 0;
|
||||
thread_state->lua_thread_state = new_state;
|
||||
thread_state->lua_thread_env_array = NULL;
|
||||
thread_state->lua_thread_begin_time = time(NULL);
|
||||
thread_state->thread_id = state_id;
|
||||
thread_state->thread_plugin_count = 0;
|
||||
thread_state->thread_state = new_state;
|
||||
thread_state->thread_env_array = NULL;
|
||||
thread_state->thread_begin_time = time(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -378,11 +470,11 @@ void thread_state_instance_destory(void *elt)
|
||||
return;
|
||||
struct lua_thread_state *thread_state = (struct lua_thread_state *)elt;
|
||||
/* 卸载所有已经注册的插件 */
|
||||
if (thread_state->lua_thread_env_array)
|
||||
utarray_free(thread_state->lua_thread_env_array);
|
||||
if (thread_state->thread_env_array)
|
||||
utarray_free(thread_state->thread_env_array);
|
||||
/* 关闭状态机 */
|
||||
if (thread_state->lua_thread_state)
|
||||
lua_close(thread_state->lua_thread_state);
|
||||
if (thread_state->thread_state)
|
||||
lua_close(thread_state->thread_state);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -403,9 +495,9 @@ int thread_state_instance_load(
|
||||
if (__glibc_unlikely(!thread_state || !schema))
|
||||
return -1;
|
||||
|
||||
lua_State *state = thread_state->lua_thread_state;
|
||||
utarray_new(thread_state->lua_thread_env_array, &plugin_env_icd);
|
||||
utarray_reserve(thread_state->lua_thread_env_array, schema->lua_config_specific_count);
|
||||
lua_State *state = thread_state->thread_state;
|
||||
utarray_new(thread_state->thread_env_array, &plugin_env_icd);
|
||||
utarray_reserve(thread_state->thread_env_array, schema->lua_config_specific_count);
|
||||
struct lua_config_specific *specific = NULL;
|
||||
|
||||
/* 读取所有插件并加入插件列表中 */
|
||||
@@ -415,21 +507,26 @@ int thread_state_instance_load(
|
||||
memset(&new_plugin_env, 0, sizeof(new_plugin_env));
|
||||
if (plugin_env_instance_init(&new_plugin_env, state, specific))
|
||||
return -2;
|
||||
utarray_push_back(thread_state->lua_thread_env_array, &new_plugin_env);
|
||||
utarray_push_back(thread_state->thread_env_array, &new_plugin_env);
|
||||
}
|
||||
|
||||
/* 依次执行插件加载函数, 调用lua中load函数 */
|
||||
struct lua_plugin_env *plugin_env = NULL;
|
||||
while ((plugin_env = utarray_next(thread_state->lua_thread_env_array, plugin_env)))
|
||||
while ((plugin_env = utarray_next(thread_state->thread_env_array, plugin_env)))
|
||||
{
|
||||
utarray_new(plugin_env->lua_plugin_env_plugin_array, &session_plugin_icd);
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, plugin_env->lua_plugin_env_ref_id);
|
||||
utarray_new(plugin_env->plugin_env_plugin_array, &session_plugin_icd);
|
||||
lua_rawgeti(state, LUA_REGISTRYINDEX, plugin_env->plugin_env_ref_id);
|
||||
/* 在lua中的全局参数中加入plugin_env指针 */
|
||||
lua_pushlightuserdata(state, plugin_env);
|
||||
lua_setfield(state, -2, PLUGIN_ENV_DEFAULT_KEY);
|
||||
lua_settop(state, 0);
|
||||
|
||||
script_execute(&plugin_env->lua_plugin_env_load_func);
|
||||
struct lua_cdata param[2];
|
||||
param[0].cdata_type = DATATYPE_POINTER;
|
||||
param[0].cdata_pointer = schema->lua_plugin_schema_st;
|
||||
param[1].cdata_type = DATATYPE_TABLE;
|
||||
param[1].cdata_table = plugin_env->plugin_env_ref_id;
|
||||
script_execute(&plugin_env->plugin_env_load_func, 2, param, 0, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -450,7 +547,7 @@ static int specific_check(struct lua_config_specific *specific)
|
||||
if (__glibc_unlikely(!specific))
|
||||
return -1;
|
||||
|
||||
if (access(specific->lua_config_specific_file, F_OK))
|
||||
if (access(specific->config_specific_file, F_OK))
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
@@ -502,7 +599,7 @@ int lua_plugin_manage_config_load(
|
||||
specific_num = toml_array_nelem(plugin_array);
|
||||
utarray_new(schema->lua_config_specific_array, &specific_icd);
|
||||
utarray_reserve(schema->lua_config_specific_array, specific_num);
|
||||
struct lua_config_specific *specific = (struct lua_config_specific *)calloc(sizeof(struct lua_config_specific), 1);
|
||||
struct lua_config_specific *specific = (struct lua_config_specific *)calloc(1, sizeof(struct lua_config_specific));
|
||||
|
||||
for (int i = 0; i < specific_num; ++i)
|
||||
{
|
||||
@@ -513,10 +610,10 @@ int lua_plugin_manage_config_load(
|
||||
const char *raw_unload_func_name = toml_raw_in(plugin, "exit");
|
||||
|
||||
/* 从配置中拷贝字符串到specific实例中 */
|
||||
if (toml_rtos(raw_filepath, &specific->lua_config_specific_file) ||
|
||||
// toml_rtos(raw_name, &specific->lua_config_specific_name) ||
|
||||
toml_rtos(raw_load_func_name, &specific->lua_config_specific_load_func) ||
|
||||
toml_rtos(raw_unload_func_name, &specific->lua_config_specific_unload_func))
|
||||
if (toml_rtos(raw_filepath, &specific->config_specific_file) ||
|
||||
// toml_rtos(raw_name, &specific->config_specific_name) ||
|
||||
toml_rtos(raw_load_func_name, &specific->config_specific_load_func) ||
|
||||
toml_rtos(raw_unload_func_name, &specific->config_specific_unload_func))
|
||||
{
|
||||
toml_free(conf);
|
||||
free(specific);
|
||||
@@ -615,9 +712,9 @@ struct lua_plugin_manage_schema *lua_plugin_manage_init(
|
||||
struct lua_config_specific *specific = NULL;
|
||||
while ((specific = utarray_next(new_schema->lua_config_specific_array, specific)))
|
||||
{
|
||||
printf("path is %s\n", specific->lua_config_specific_file);
|
||||
printf("load is %s\n", specific->lua_config_specific_load_func);
|
||||
printf("unload is %s\n", specific->lua_config_specific_unload_func);
|
||||
printf("path is %s\n", specific->config_specific_file);
|
||||
printf("load is %s\n", specific->config_specific_load_func);
|
||||
printf("unload is %s\n", specific->config_specific_unload_func);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -47,6 +47,23 @@
|
||||
* int thread_state_instance_load;
|
||||
* int lua_plugin_manage_config_load;
|
||||
* int lua_plugin_manage_thread_load;
|
||||
*
|
||||
* 08-06
|
||||
* 完成数据相关操作, 并补全函数script_execute
|
||||
* 完成注册至C插件管理器中的session_ctx_new_func及session_ctx_free_func函数
|
||||
* 1. 声明并定义结构
|
||||
* struct lua_cdata;
|
||||
* struct lua_context;
|
||||
* 2. 声明函数
|
||||
* int lua_cdata_push_stack;
|
||||
* int lua_cdata_pop_stack;
|
||||
* void lua_cdata_destory;
|
||||
* struct lua_context * lua_context_new;
|
||||
* int lua_context_push_stack;
|
||||
* void lua_context_free;
|
||||
*
|
||||
* void *lpm_ctx_new_func;
|
||||
* void lpm_ctx_free_func;
|
||||
************************************************************************/
|
||||
#ifndef LUA_PLUGIN_MANAGE_INTERNAL_H
|
||||
#define LUA_PLUGIN_MANAGE_INTERNAL_H
|
||||
@@ -62,7 +79,7 @@
|
||||
#include <time.h>
|
||||
|
||||
/* ***** ***** ***** ***** ***** ***** */
|
||||
|
||||
/* 此部分主要功能为C向lua中注册函数及数据, 实现在lua_plugin_binding.c中 */
|
||||
/* 需要注册至lua中的函数 */
|
||||
struct lua_binding_function
|
||||
{
|
||||
@@ -88,6 +105,8 @@ int lua_cbinding_function_remove(lua_State *state, const char *function_name, co
|
||||
enum DATATYPE
|
||||
{
|
||||
DATATYPE_BEGIN = 0,
|
||||
/* nil类型 */
|
||||
DATATYPE_NIL,
|
||||
/* bool类型 */
|
||||
DATATYPE_BOOL,
|
||||
/* int类型 */
|
||||
@@ -101,6 +120,7 @@ enum DATATYPE
|
||||
DATATYPE_TABLE,
|
||||
/* 指针类型 */
|
||||
DATATYPE_POINTER,
|
||||
DATATYPE_CONTEXT,
|
||||
DATATYPE_END
|
||||
};
|
||||
|
||||
@@ -132,11 +152,48 @@ int lua_cbinding_functions(lua_State *state);
|
||||
int lua_cbinding_datas(lua_State *state);
|
||||
|
||||
/* ***** ***** ***** ***** ***** ***** */
|
||||
/* 此部分主要用于lua与C之间的数据转换与传递, 实现在lua_plugin_data.c中 */
|
||||
struct lua_cdata;
|
||||
// struct lua_ctable;
|
||||
struct lua_context;
|
||||
|
||||
/* 保存lua数据的结构 */
|
||||
struct lua_cdata {
|
||||
enum DATATYPE cdata_type;
|
||||
union {
|
||||
int cdata_bool;
|
||||
int cdata_int;
|
||||
double cdata_num;
|
||||
char * cdata_string;
|
||||
/* table暂时只有plugin_env场景下使用, 暂时使用索引进行操作 */
|
||||
int cdata_table;
|
||||
void * cdata_pointer;
|
||||
struct lua_context * cdata_context;
|
||||
};
|
||||
};
|
||||
|
||||
/* 将一个data结构入栈 */
|
||||
int lua_cdata_push_stack(lua_State * state, struct lua_cdata * cdata);
|
||||
/* 从栈中弹出一个元素, 并保存在data结构中 */
|
||||
int lua_cdata_pop_stack(lua_State * state, struct lua_cdata * cdata);
|
||||
/* 销毁一个data结构, 只有string类型需要调用此函数, 其他的情况直接释放即可 */
|
||||
void lua_cdata_destory(struct lua_cdata * cdata);
|
||||
|
||||
/* 上下文结构, 保存临时数据 */
|
||||
struct lua_context {
|
||||
lua_State * context_state;
|
||||
int context_ref_id;
|
||||
};
|
||||
|
||||
/* 在状态机中生成一个context */
|
||||
struct lua_context * lua_context_new(lua_State * state);
|
||||
/* 将一个context入栈 */
|
||||
int lua_context_push_stack(struct lua_context * context);
|
||||
/* 释放一个context */
|
||||
void lua_context_free(struct lua_context * context);
|
||||
|
||||
/* ***** ***** ***** ***** ***** ***** */
|
||||
|
||||
/* 此部分主要为插件管理及配置管理相关功能, 实现在lua_plugin_manage.c中 */
|
||||
struct lua_config_specific;
|
||||
struct lua_script;
|
||||
struct lua_session_plugin;
|
||||
@@ -148,13 +205,13 @@ struct lua_plugin_manage_schema;
|
||||
struct lua_config_specific
|
||||
{
|
||||
/* 插件需要使用的文件名 */
|
||||
char *lua_config_specific_file;
|
||||
char *config_specific_file;
|
||||
/* 插件名称 */
|
||||
// char *lua_config_specific_name;
|
||||
// char *config_specific_name;
|
||||
/* 加载插件需要调用的函数名称 */
|
||||
char *lua_config_specific_load_func;
|
||||
char *config_specific_load_func;
|
||||
/* 卸载插件需要调用的函数名称 */
|
||||
char *lua_config_specific_unload_func;
|
||||
char *config_specific_unload_func;
|
||||
};
|
||||
|
||||
void specific_instance_copy(void *dst, const void *src);
|
||||
@@ -184,7 +241,7 @@ struct lua_script
|
||||
int script_instance_init_byname(struct lua_script *script, lua_State *state, const char *filepath, const char *funcname);
|
||||
int script_instance_init_byrefid(struct lua_script *script, lua_State *state, int ref_id);
|
||||
void script_instance_clean(struct lua_script *script);
|
||||
int script_execute(struct lua_script *script);
|
||||
int script_execute(struct lua_script *script, int pcount, struct lua_cdata * param, int rmaxcount, struct lua_cdata * rvalue);
|
||||
|
||||
/* 每一个插件的函数信息 */
|
||||
struct lua_session_plugin
|
||||
@@ -209,21 +266,21 @@ void session_plugin_instance_destory(void *elt);
|
||||
struct lua_plugin_env
|
||||
{
|
||||
/* 插件注册的状态机 */
|
||||
lua_State *lua_plugin_env_state;
|
||||
lua_State *plugin_env_state;
|
||||
/* 该环境数据中包含的所有插件列表 */
|
||||
UT_array *lua_plugin_env_plugin_array;
|
||||
UT_array *plugin_env_plugin_array;
|
||||
|
||||
/* 加载插件的lua函数 */
|
||||
struct lua_script lua_plugin_env_load_func;
|
||||
struct lua_script plugin_env_load_func;
|
||||
/* 卸载插件的lua函数 */
|
||||
struct lua_script lua_plugin_env_unload_func;
|
||||
struct lua_script plugin_env_unload_func;
|
||||
|
||||
/* 该插件运行环境数据的名称, 在创建时同时在状态机中创建该名称的命名空间 */
|
||||
/* 插件申请lua内的全局变量可以保存在该命名空间内, 防止被其他内容覆盖 */
|
||||
// char * lua_plugin_env_name;
|
||||
// char *plugin_env_name;
|
||||
|
||||
/* 在lua中保存运行数据的引用ID */
|
||||
int lua_plugin_env_ref_id; /* plugin_env */
|
||||
int plugin_env_ref_id; /* plugin_env */
|
||||
};
|
||||
|
||||
/* 此时不创建session_array, 在调用load函数过程中创建 */
|
||||
@@ -234,16 +291,16 @@ void plugin_env_instance_destory(void *elt);
|
||||
struct lua_thread_state
|
||||
{
|
||||
/* 创建状态机的线程ID */
|
||||
int lua_thread_id;
|
||||
int thread_id;
|
||||
/* 已经插入的插件数量 */
|
||||
int lua_thread_plugin_count;
|
||||
int thread_plugin_count;
|
||||
/* 生成的状态机 */
|
||||
lua_State *lua_thread_state;
|
||||
lua_State *thread_state;
|
||||
// struct lua_pl_state_private * lua_thread_private;
|
||||
/* 该线程状态机中注册的插件列表 */
|
||||
UT_array *lua_thread_env_array;
|
||||
UT_array *thread_env_array;
|
||||
/* 状态机的启动时间 */
|
||||
time_t lua_thread_begin_time;
|
||||
time_t thread_begin_time;
|
||||
};
|
||||
|
||||
int thread_state_instance_init(struct lua_thread_state *thread_state, int state_id);
|
||||
@@ -262,11 +319,13 @@ struct lua_plugin_manage_schema
|
||||
/* 防止参数错误, 暂时定一个上限 */
|
||||
#define LUA_PLUGIN_MANAGE_MAX_THREAD_COUNT 10
|
||||
|
||||
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_on_session_msg_func(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_env);
|
||||
|
||||
int lua_plugin_manage_config_load(struct lua_plugin_manage_schema *schema, const char *config_file_name);
|
||||
int lua_plugin_manage_thread_load(struct lua_plugin_manage_schema *schema, int thread_count);
|
||||
|
||||
/* ***** ***** ***** ***** ***** ***** */
|
||||
/* 此部分为注册至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_on_session_msg_func(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_env);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user