【新增】实现数据管理能力

This commit is contained in:
niubinghui
2024-08-06 16:16:34 +08:00
parent dc63983f77
commit 0f5cbff974
6 changed files with 601 additions and 87 deletions

33
src/Makefile Normal file
View 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)

View File

@@ -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
View 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
View 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;
}

View File

@@ -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, &param[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, &param, 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

View File

@@ -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