【修改】修改schema设计思路,将线程与插件作为数组进行管理,节约运行内存
This commit is contained in:
@@ -19,7 +19,17 @@
|
|||||||
|
|
||||||
#include "stellar.h"
|
#include "stellar.h"
|
||||||
|
|
||||||
|
struct lua_config_specific
|
||||||
|
{
|
||||||
|
/* 插件需要使用的文件名 */
|
||||||
|
char *config_specific_file;
|
||||||
|
/* 加载插件需要调用的函数名称 */
|
||||||
|
char *config_specific_load_func;
|
||||||
|
/* 卸载插件需要调用的函数名称 */
|
||||||
|
char *config_specific_unload_func;
|
||||||
|
};
|
||||||
|
|
||||||
struct lua_plugin_manage_schema;
|
struct lua_plugin_manage_schema;
|
||||||
|
|
||||||
struct lua_plugin_manage_schema * lua_plugin_manage_init(struct stellar * st, const char * config_file_path);
|
struct lua_plugin_manage_schema *lua_plugin_manage_init(struct stellar *st, int specific_count, struct lua_config_specific *specific);
|
||||||
void lua_plugin_manage_exit(struct lua_plugin_manage_schema * lua_plug_mgr);
|
void lua_plugin_manage_exit(struct lua_plugin_manage_schema *lua_plug_mgr);
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
* int lua_cbinding_datas;
|
* int lua_cbinding_datas;
|
||||||
* int lua_plugin_manage_regist;
|
* int lua_plugin_manage_regist;
|
||||||
* ** 注册函数lua_plugin_manage_session_regist还需要补充
|
* ** 注册函数lua_plugin_manage_session_regist还需要补充
|
||||||
|
*
|
||||||
|
* 08-12
|
||||||
|
* 1. 修改函数lua_cbinding_function, 参数与lua_cbinding_data保持统一
|
||||||
|
* 2. 修改部分函数返回值, 使用枚举代替错误码返回值, 方便统一处理
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include "lua_plugin_manage_internal.h"
|
#include "lua_plugin_manage_internal.h"
|
||||||
|
|
||||||
@@ -25,11 +29,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* 需要注册至lua中供lua调用的所有函数原型 */
|
/* 需要注册至lua中供lua调用的所有函数原型 */
|
||||||
int lua_plugin_manage_regist(lua_State * state);
|
int lua_plugin_manage_regist(lua_State *state);
|
||||||
int lua_session_get_id(lua_State * state);
|
int lua_session_get_id(lua_State *state);
|
||||||
int lua_session_set_id(lua_State * state);
|
int lua_session_set_id(lua_State *state);
|
||||||
int lua_session_get_type(lua_State * state);
|
int lua_session_get_type(lua_State *state);
|
||||||
int lua_session_set_type(lua_State * state);
|
int lua_session_set_type(lua_State *state);
|
||||||
|
|
||||||
/* 需要注册至状态机中的函数定义在链表中, 会依次完成注册 */
|
/* 需要注册至状态机中的函数定义在链表中, 会依次完成注册 */
|
||||||
struct lua_binding_function lua_bind_functions[] = {
|
struct lua_binding_function lua_bind_functions[] = {
|
||||||
@@ -52,7 +56,7 @@ struct lua_binding_data lua_bind_datas[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* 向lua状态机中注册一个函数 */
|
/* 向lua状态机中注册一个函数 */
|
||||||
int lua_cbinding_function(lua_State *state, lua_CFunction bind_function, const char *function_name, const char *space_name);
|
int lua_cbinding_function(lua_State *state, struct lua_binding_function *function);
|
||||||
/* 从lua状态机中移除一个已经注册的函数 */
|
/* 从lua状态机中移除一个已经注册的函数 */
|
||||||
int lua_cbinding_function_remove(lua_State *state, const char *function_name, const char *space_name);
|
int lua_cbinding_function_remove(lua_State *state, const char *function_name, const char *space_name);
|
||||||
/* 将一个全局数据注册至状态机中 */
|
/* 将一个全局数据注册至状态机中 */
|
||||||
@@ -62,38 +66,38 @@ int lua_cbinding_data_remove(lua_State *state, const char *data_name, const char
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: lua_cbinding_function
|
* Function: lua_cbinding_function
|
||||||
* Input: | lua_State * | state | 需要注册函数的状态机
|
* Input: | lua_State * | state | 需要注册函数的状态机
|
||||||
* | lua_CFunction | bind_function | 需要注册的函数
|
* | struct lua_binding_function * | function | 需要绑定的function函数结构
|
||||||
* | const char * | function_name | 注册函数的名称
|
|
||||||
* | const char * | space_name | 注册函数的命名空间
|
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | 0 | 注册成功
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -1 | 传入的参数有错误
|
|
||||||
* | -2 | 命名空间已经存在, 且命名空间不是table类型, 无法新增成员
|
|
||||||
* | -3 | 命名空间中已经存在函数名称对应成员, 无法完成覆盖
|
|
||||||
* | -4 | 存在全局的函数名称, 无法完成注册
|
|
||||||
* Description: 将一个C函数注册至lua中
|
* Description: 将一个C函数注册至lua中
|
||||||
*/
|
*/
|
||||||
int lua_cbinding_function(
|
int lua_cbinding_function(
|
||||||
lua_State *state,
|
lua_State *state,
|
||||||
lua_CFunction bind_function,
|
struct lua_binding_function *bind_function)
|
||||||
const char *function_name,
|
|
||||||
const char *space_name)
|
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !bind_function || !function_name))
|
if (__glibc_unlikely(!state || !bind_function))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
if (__glibc_unlikely(!bind_function->function || !bind_function->function_name))
|
||||||
|
return PARAM_ERR;
|
||||||
|
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
||||||
|
LOGDEBUG("bind function to state, function %p, name %s, spacename %s",
|
||||||
|
bind_function->function,
|
||||||
|
bind_function->function_name,
|
||||||
|
(bind_function->space_name) ? bind_function->space_name : "no");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (space_name)
|
if (bind_function->space_name)
|
||||||
{
|
{
|
||||||
/* 包含space_name, 调用时为 space_name.function_name */
|
/* 包含space_name, 调用时为 space_name.function_name */
|
||||||
lua_getglobal(state, space_name);
|
lua_getglobal(state, bind_function->space_name);
|
||||||
if (lua_gettop(state) == 0 || lua_type(state, -1) == LUA_TNIL)
|
if (lua_gettop(state) == 0 || lua_type(state, -1) == LUA_TNIL)
|
||||||
{
|
{
|
||||||
/* 没有该命名空间, 创建一个 */
|
/* 没有该命名空间, 创建一个 */
|
||||||
lua_newtable(state);
|
lua_newtable(state);
|
||||||
lua_setglobal(state, space_name);
|
lua_setglobal(state, bind_function->space_name);
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
lua_getglobal(state, space_name);
|
lua_getglobal(state, bind_function->space_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -102,40 +106,40 @@ int lua_cbinding_function(
|
|||||||
{
|
{
|
||||||
/* spacename已经被占用, 并且不是table, 无法插入数据 */
|
/* spacename已经被占用, 并且不是table, 无法插入数据 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -2;
|
return BIND_NAMESPACE_TYPE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_getfield(state, -1, function_name);
|
lua_getfield(state, -1, bind_function->function_name);
|
||||||
if (lua_type(state, -1) != LUA_TNIL)
|
if (lua_type(state, -1) != LUA_TNIL)
|
||||||
{
|
{
|
||||||
/* 在待插入的global table中存在与function_name重名的成员 */
|
/* 在待插入的global table中存在与function_name重名的成员 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -3;
|
return BIND_FUNCTION_TYPE_ERR;
|
||||||
}
|
}
|
||||||
lua_pop(state, 1); /* 正确的情况下此时栈顶为nil, 弹出一个nil值 */
|
lua_pop(state, 1); /* 正确的情况下此时栈顶为nil, 弹出一个nil值 */
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushcfunction(state, bind_function);
|
lua_pushcfunction(state, bind_function->function);
|
||||||
lua_setfield(state, -2, function_name);
|
lua_setfield(state, -2, bind_function->function_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lua_getglobal(state, function_name);
|
lua_getglobal(state, bind_function->function_name);
|
||||||
if (lua_type(state, -1) != LUA_TNIL)
|
if (lua_type(state, -1) != LUA_TNIL)
|
||||||
{
|
{
|
||||||
/* 存在与function_name重名的全局成员 */
|
/* 存在与function_name重名的全局成员 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -4;
|
return BIND_FUNCTION_TYPE_ERR;
|
||||||
}
|
}
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
|
|
||||||
/* 不包含space_name, 调用时直接使用function_name调用 */
|
/* 不包含space_name, 调用时直接使用function_name调用 */
|
||||||
lua_pushcfunction(state, bind_function);
|
lua_pushcfunction(state, bind_function->function);
|
||||||
lua_setglobal(state, function_name);
|
lua_setglobal(state, bind_function->function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,11 +148,7 @@ int lua_cbinding_function(
|
|||||||
* | const char * | function_name | 需要删除的函数名称
|
* | const char * | function_name | 需要删除的函数名称
|
||||||
* | const char * | space_name | 需要删除的命名空间名称
|
* | const char * | space_name | 需要删除的命名空间名称
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | 0 | 删除成功
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 命名空间存在但不是一个table
|
|
||||||
* | -3 | 命名空间中存在函数名称对应成员, 但是类型不是函数
|
|
||||||
* | -4 | 函数名称对应的成员不是一个函数
|
|
||||||
* Description: 从状态机中删除一个C注册的函数, 删除过程中将该函数在lua状态的引用置为nil
|
* Description: 从状态机中删除一个C注册的函数, 删除过程中将该函数在lua状态的引用置为nil
|
||||||
*/
|
*/
|
||||||
int lua_cbinding_function_remove(
|
int lua_cbinding_function_remove(
|
||||||
@@ -157,7 +157,7 @@ int lua_cbinding_function_remove(
|
|||||||
const char *space_name)
|
const char *space_name)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !function_name))
|
if (__glibc_unlikely(!state || !function_name))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
|
||||||
if (space_name)
|
if (space_name)
|
||||||
{
|
{
|
||||||
@@ -167,7 +167,7 @@ int lua_cbinding_function_remove(
|
|||||||
{
|
{
|
||||||
/* 命名空间存在且不是table */
|
/* 命名空间存在且不是table */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -2;
|
return BIND_NAMESPACE_TYPE_ERR;
|
||||||
}
|
}
|
||||||
/* 检查该命名空间内是否存在function_name */
|
/* 检查该命名空间内是否存在function_name */
|
||||||
lua_getfield(state, -1, function_name);
|
lua_getfield(state, -1, function_name);
|
||||||
@@ -175,7 +175,7 @@ int lua_cbinding_function_remove(
|
|||||||
{
|
{
|
||||||
/* 命名空间存在内部元素名称为function_name, 但是类型不符 */
|
/* 命名空间存在内部元素名称为function_name, 但是类型不符 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -3;
|
return BIND_FUNCTION_TYPE_ERR;
|
||||||
}
|
}
|
||||||
/* 删除该函数 */
|
/* 删除该函数 */
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
@@ -190,7 +190,7 @@ int lua_cbinding_function_remove(
|
|||||||
{
|
{
|
||||||
/* 类型不符 */
|
/* 类型不符 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -4;
|
return BIND_FUNCTION_TYPE_ERR;
|
||||||
}
|
}
|
||||||
/* 删除该函数 */
|
/* 删除该函数 */
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
@@ -199,20 +199,15 @@ int lua_cbinding_function_remove(
|
|||||||
}
|
}
|
||||||
|
|
||||||
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: lua_cbinding_data
|
* Function: lua_cbinding_data
|
||||||
* Input: | lua_State * | state | 需要注册数据的状态机
|
* Input: | lua_State * | state | 需要注册数据的状态机
|
||||||
* | struct lua_binding_data * | data | 需要注册至状态机中的数据
|
* | struct lua_binding_data * | data | 需要注册至状态机中的数据
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | 0 | 注册成功
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -1 | 传入的参数有错误
|
|
||||||
* | -2 | 命名空间已经存在, 且命名空间不是table类型, 无法新增成员
|
|
||||||
* | -3 | 命名空间中已经存在函数名称对应成员, 无法完成覆盖
|
|
||||||
* | -4 | 无法识别data的数据类型
|
|
||||||
* | -5 | 全局变量名称已经有成员, 不为空
|
|
||||||
* Description: 将一个变量注册至lua状态机中
|
* Description: 将一个变量注册至lua状态机中
|
||||||
*/
|
*/
|
||||||
int lua_cbinding_data(
|
int lua_cbinding_data(
|
||||||
@@ -221,14 +216,18 @@ int lua_cbinding_data(
|
|||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !data))
|
if (__glibc_unlikely(!state || !data))
|
||||||
{
|
{
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
}
|
}
|
||||||
enum DATATYPE data_type = data->binding_data_type;
|
enum DATATYPE data_type = data->data_type;
|
||||||
char *value = data->binding_data_value;
|
char *value = data->data_value;
|
||||||
char *data_name = data->binding_data_name;
|
char *data_name = data->data_name;
|
||||||
char *space_name = data->binding_data_space_name;
|
char *space_name = data->space_name;
|
||||||
if (__glibc_unlikely(!value || !data_name))
|
if (__glibc_unlikely(!value || !data_name))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
||||||
|
LOGDEBUG("bind data to state, type %d, data %s, name %s, spacename %s",
|
||||||
|
data_type, value, data_name, (space_name) ? space_name : "no");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (space_name)
|
if (space_name)
|
||||||
{
|
{
|
||||||
@@ -249,7 +248,7 @@ int lua_cbinding_data(
|
|||||||
{
|
{
|
||||||
/* spacename已经被占用, 并且不是table, 无法插入数据 */
|
/* spacename已经被占用, 并且不是table, 无法插入数据 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -2;
|
return BIND_NAMESPACE_TYPE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_getfield(state, -1, data_name);
|
lua_getfield(state, -1, data_name);
|
||||||
@@ -257,7 +256,7 @@ int lua_cbinding_data(
|
|||||||
{
|
{
|
||||||
/* 在待插入的global table中存在与function_name重名的成员 */
|
/* 在待插入的global table中存在与function_name重名的成员 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -3;
|
return BIND_DATA_TYPE_ERR;
|
||||||
}
|
}
|
||||||
lua_pop(state, 1); /* 正确的情况下此时栈顶为nil, 弹出一个nil值 */
|
lua_pop(state, 1); /* 正确的情况下此时栈顶为nil, 弹出一个nil值 */
|
||||||
}
|
}
|
||||||
@@ -268,7 +267,7 @@ int lua_cbinding_data(
|
|||||||
case DATATYPE_BOOL:
|
case DATATYPE_BOOL:
|
||||||
if (strstr(value, "true") || strstr(value, "TRUE"))
|
if (strstr(value, "true") || strstr(value, "TRUE"))
|
||||||
lua_pushboolean(state, 1);
|
lua_pushboolean(state, 1);
|
||||||
else if (strstr(value, "false") || strstr(value, "false"))
|
else if (strstr(value, "false") || strstr(value, "FALSE"))
|
||||||
lua_pushboolean(state, 0);
|
lua_pushboolean(state, 0);
|
||||||
break;
|
break;
|
||||||
case DATATYPE_INT:
|
case DATATYPE_INT:
|
||||||
@@ -283,7 +282,7 @@ int lua_cbinding_data(
|
|||||||
default:
|
default:
|
||||||
/* 未识别的类型 */
|
/* 未识别的类型 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -4;
|
return BIND_DATA_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
lua_setfield(state, -2, data_name);
|
lua_setfield(state, -2, data_name);
|
||||||
}
|
}
|
||||||
@@ -294,7 +293,7 @@ int lua_cbinding_data(
|
|||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
/* 存在与data_name重名的全局成员 */
|
/* 存在与data_name重名的全局成员 */
|
||||||
return -5;
|
return BIND_DATA_TYPE_ERR;
|
||||||
}
|
}
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
|
|
||||||
@@ -304,7 +303,7 @@ int lua_cbinding_data(
|
|||||||
case DATATYPE_BOOL:
|
case DATATYPE_BOOL:
|
||||||
if (strstr(value, "true") || strstr(value, "TRUE"))
|
if (strstr(value, "true") || strstr(value, "TRUE"))
|
||||||
lua_pushboolean(state, 1);
|
lua_pushboolean(state, 1);
|
||||||
else if (strstr(value, "false") || strstr(value, "false"))
|
else if (strstr(value, "false") || strstr(value, "FALSE"))
|
||||||
lua_pushboolean(state, 0);
|
lua_pushboolean(state, 0);
|
||||||
break;
|
break;
|
||||||
case DATATYPE_INT:
|
case DATATYPE_INT:
|
||||||
@@ -319,13 +318,13 @@ int lua_cbinding_data(
|
|||||||
default:
|
default:
|
||||||
/* 未识别的类型 */
|
/* 未识别的类型 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -4;
|
return BIND_DATA_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
lua_setglobal(state, data_name);
|
lua_setglobal(state, data_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -334,11 +333,7 @@ int lua_cbinding_data(
|
|||||||
* | const char * | data_name | 需要删除的数据名称
|
* | const char * | data_name | 需要删除的数据名称
|
||||||
* | const char * | space_name | 需要删除的命名空间名称
|
* | const char * | space_name | 需要删除的命名空间名称
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | 0 | 删除成功
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 命名空间存在但不是一个table
|
|
||||||
* | -3 | 命名空间中存在数据名称对应成员, 但是类型不符
|
|
||||||
* | -4 | 函数名称对应的成员类型不符
|
|
||||||
* Description: 从状态机中删除一个C注册的数据, 删除过程中将该名称在lua状态的引用置为nil
|
* Description: 从状态机中删除一个C注册的数据, 删除过程中将该名称在lua状态的引用置为nil
|
||||||
*/
|
*/
|
||||||
int lua_cbinding_data_remove(
|
int lua_cbinding_data_remove(
|
||||||
@@ -347,7 +342,7 @@ int lua_cbinding_data_remove(
|
|||||||
const char *space_name)
|
const char *space_name)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !data_name))
|
if (__glibc_unlikely(!state || !data_name))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
|
||||||
if (space_name)
|
if (space_name)
|
||||||
{
|
{
|
||||||
@@ -357,7 +352,7 @@ int lua_cbinding_data_remove(
|
|||||||
{
|
{
|
||||||
/* 命名空间存在且不是table */
|
/* 命名空间存在且不是table */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -2;
|
return BIND_NAMESPACE_TYPE_ERR;
|
||||||
}
|
}
|
||||||
/* 检查该命名空间内是否存在data_name */
|
/* 检查该命名空间内是否存在data_name */
|
||||||
lua_getfield(state, -1, data_name);
|
lua_getfield(state, -1, data_name);
|
||||||
@@ -366,13 +361,13 @@ int lua_cbinding_data_remove(
|
|||||||
{
|
{
|
||||||
/* 命名空间存在内部元素名称为data_name, 但是类型不符 */
|
/* 命名空间存在内部元素名称为data_name, 但是类型不符 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -3;
|
return BIND_DATA_TYPE_ERR;
|
||||||
}
|
}
|
||||||
else if (data_type == LUA_TNIL)
|
else if (data_type == LUA_TNIL)
|
||||||
{
|
{
|
||||||
/* 没有该名称的元素 */
|
/* 没有该名称的元素 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* 删除该函数 */
|
/* 删除该函数 */
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
@@ -388,13 +383,13 @@ int lua_cbinding_data_remove(
|
|||||||
{
|
{
|
||||||
/* 类型不符 */
|
/* 类型不符 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return -4;
|
return BIND_DATA_TYPE_ERR;
|
||||||
}
|
}
|
||||||
else if (data_type == LUA_TNIL)
|
else if (data_type == LUA_TNIL)
|
||||||
{
|
{
|
||||||
/* 没有该名称的元素 */
|
/* 没有该名称的元素 */
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* 删除该函数 */
|
/* 删除该函数 */
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
@@ -403,7 +398,7 @@ int lua_cbinding_data_remove(
|
|||||||
}
|
}
|
||||||
|
|
||||||
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
lua_settop(state, 0); /* 操作完成, 弹出所有元素 */
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -412,28 +407,25 @@ int lua_cbinding_data_remove(
|
|||||||
* Output:
|
* Output:
|
||||||
* Return: | -1 | 参数错误
|
* Return: | -1 | 参数错误
|
||||||
* | 0 | 成功
|
* | 0 | 成功
|
||||||
* | >0 | 绑定有错的函数数量
|
* | >0 | 绑定出错的数据数量
|
||||||
* Description: 绑定所有需要在lua中调用的C函数
|
* Description: 绑定所有需要在lua中调用的C函数
|
||||||
*/
|
*/
|
||||||
int lua_cbinding_functions(lua_State *state)
|
int lua_cbinding_functions(lua_State *state)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state))
|
if (__glibc_unlikely(!state))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
int bind_function_count = sizeof(lua_bind_functions) / sizeof(struct lua_binding_function);
|
int bind_function_count = sizeof(lua_bind_functions) / sizeof(struct lua_binding_function);
|
||||||
|
|
||||||
int bind_ret = 0;
|
int bind_ret = 0;
|
||||||
int failed_count = 0;
|
int failed_count = 0;
|
||||||
for (int i = 0; i < bind_function_count; ++i)
|
for (int i = 0; i < bind_function_count; ++i)
|
||||||
{
|
{
|
||||||
if (lua_bind_functions[i].binding_function && lua_bind_functions[i].binding_function_name)
|
if (lua_bind_functions[i].function && lua_bind_functions[i].function_name)
|
||||||
{
|
{
|
||||||
bind_ret = lua_cbinding_function(state,
|
bind_ret = lua_cbinding_function(state, &lua_bind_functions[i]);
|
||||||
lua_bind_functions[i].binding_function,
|
|
||||||
(const char *)lua_bind_functions[i].binding_function_name,
|
|
||||||
(const char *)lua_bind_functions[i].binding_function_space_name);
|
|
||||||
if (bind_ret)
|
if (bind_ret)
|
||||||
{
|
{
|
||||||
LOGERROR("binding function failed, ret is %d, function name is %s\n", bind_ret, lua_bind_functions[i].binding_function_name);
|
LOGERROR("binding function failed, ret is %d, function name is %s\n", bind_ret, lua_bind_functions[i].function_name);
|
||||||
failed_count += 1;
|
failed_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,12 +452,12 @@ int lua_cbinding_datas(lua_State *state)
|
|||||||
int failed_count = 0;
|
int failed_count = 0;
|
||||||
for (int i = 0; i < bind_data_count; ++i)
|
for (int i = 0; i < bind_data_count; ++i)
|
||||||
{
|
{
|
||||||
if (lua_bind_datas[i].binding_data_value && lua_bind_datas[i].binding_data_name)
|
if (lua_bind_datas[i].data_value && lua_bind_datas[i].data_name)
|
||||||
{
|
{
|
||||||
bind_ret = lua_cbinding_data(state, &lua_bind_datas[i]);
|
bind_ret = lua_cbinding_data(state, &lua_bind_datas[i]);
|
||||||
if (bind_ret)
|
if (bind_ret)
|
||||||
{
|
{
|
||||||
LOGERROR("binding data failed, ret is %d, data is [%s]%s", bind_ret, lua_bind_datas[i].binding_data_name, lua_bind_datas[i].binding_data_value);
|
LOGERROR("binding data failed, ret is %d, data is [%s]%s", bind_ret, lua_bind_datas[i].data_name, lua_bind_datas[i].data_value);
|
||||||
failed_count += 1;
|
failed_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -484,7 +476,7 @@ int lua_plugin_manage_regist(lua_State *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 参数类型检查 */
|
/* 参数类型检查 */
|
||||||
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA || lua_type(state, -2) != LUA_TFUNCTION ||
|
if (lua_type(state, -1) != LUA_TTABLE || lua_type(state, -2) != LUA_TFUNCTION ||
|
||||||
lua_type(state, -3) != LUA_TFUNCTION || lua_type(state, -4) != LUA_TLIGHTUSERDATA)
|
lua_type(state, -3) != LUA_TFUNCTION || lua_type(state, -4) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
@@ -492,13 +484,16 @@ int lua_plugin_manage_regist(lua_State *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 取出处理第四个参数 */
|
/* 取出处理第四个参数 */
|
||||||
struct lua_plugin_env *plugin_env = (struct lua_plugin_env *)lua_topointer(state, -1); /* stack 4 */
|
lua_getfield(state, -1, LUA_PLUGIN_ENV_DEFAULT_KEY); /* stack 4, table中取出对应结构的指针 */
|
||||||
if (!plugin_env)
|
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
lua_pop(state, 1);
|
struct lua_model *plugin_env = (struct lua_model *)lua_topointer(state, -1);
|
||||||
|
lua_pop(state, 2);
|
||||||
|
// debug_lua_state_stack(state, 0, "here");
|
||||||
|
// printf("env pointer is %p\n", plugin_env);
|
||||||
|
|
||||||
/* 取出处理第三个参数 */
|
/* 取出处理第三个参数 */
|
||||||
int ctx_free_id = luaL_ref(state, LUA_REGISTRYINDEX); /* stack 3 */
|
int ctx_free_id = luaL_ref(state, LUA_REGISTRYINDEX); /* stack 3 */
|
||||||
@@ -517,8 +512,9 @@ int lua_plugin_manage_regist(lua_State *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 取出处理第一个参数 */
|
/* 取出处理第一个参数 */
|
||||||
struct stellar * st = (struct stellar *)lua_topointer(state, -1); /* stack 1 */
|
struct stellar *st = (struct stellar *)lua_topointer(state, -1); /* stack 1 */
|
||||||
if ( !st ) {
|
if (!st)
|
||||||
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -527,15 +523,43 @@ int lua_plugin_manage_regist(lua_State *state)
|
|||||||
/* 在stellar中注册, 获取注册id */
|
/* 在stellar中注册, 获取注册id */
|
||||||
int plugin_id = stellar_session_plugin_register(st, lpm_ctx_new_func, lpm_ctx_free_func, (void *)plugin_env);
|
int plugin_id = stellar_session_plugin_register(st, lpm_ctx_new_func, lpm_ctx_free_func, (void *)plugin_env);
|
||||||
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
||||||
LOGDEBUG("now regist new plugin, plugin id is %d\n", plugin_id);
|
LOGDEBUG("now regist new plugin, plugin id is %d, %d, %d\n", plugin_id, ctx_new_id, ctx_free_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 将注册完成的新插件插入到队列中 */
|
/* TODO: 如果运行完全符合预期的话, 理论上仅有thread 0在此处需要插入新的插件, 且不应该有错误
|
||||||
struct lua_session_plugin session_plugin;
|
* 对于其他线程这里应该直接检查ref id是否一致即可, 按理说不应该再插入新插件
|
||||||
memset(&session_plugin, 0, sizeof(session_plugin));
|
* 后续可以修改为根据线程号执行不同的处理流程
|
||||||
session_plugin_instance_init(&session_plugin, state, plugin_id, ctx_new_id, ctx_free_id);
|
*/
|
||||||
|
/* 如果在其他线程中已经完成过注册 */
|
||||||
|
struct lua_plugin *search_plugin = NULL;
|
||||||
|
while ((search_plugin = utarray_next(plugin_env->plugin_array, search_plugin)))
|
||||||
|
{
|
||||||
|
if (search_plugin->plugin_id == plugin_id)
|
||||||
|
{
|
||||||
|
/* 初始化过程中已经进行过加载 */
|
||||||
|
if (search_plugin->ctx_new_ref != ctx_new_id || search_plugin->ctx_free_ref != ctx_free_id)
|
||||||
|
{
|
||||||
|
LOGERROR("regist plugin, same id with different function ref");
|
||||||
|
LOGERROR("plugin id %d, registed %d, %d, new ref %d, %d", plugin_id,
|
||||||
|
search_plugin->ctx_new_ref, search_plugin->ctx_free_ref,
|
||||||
|
ctx_new_id, ctx_free_id);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lua_settop(state, 0);
|
||||||
|
lua_pushinteger(state, plugin_id);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
utarray_push_back(plugin_env->plugin_env_plugin_array, &session_plugin);
|
/* 将注册完成的新插件插入到队列中 */
|
||||||
|
struct lua_plugin new_plugin;
|
||||||
|
memset(&new_plugin, 0, sizeof(new_plugin));
|
||||||
|
new_plugin.plugin_id = plugin_id;
|
||||||
|
new_plugin.ctx_new_ref = ctx_new_id;
|
||||||
|
new_plugin.ctx_free_ref = ctx_free_id;
|
||||||
|
utarray_push_back(plugin_env->plugin_array, &new_plugin);
|
||||||
|
plugin_env->plugin_count += 1;
|
||||||
|
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
lua_pushinteger(state, plugin_id);
|
lua_pushinteger(state, plugin_id);
|
||||||
@@ -543,7 +567,7 @@ int lua_plugin_manage_regist(lua_State *state)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_session_get_id(lua_State * state)
|
int lua_session_get_id(lua_State *state)
|
||||||
{
|
{
|
||||||
/* 参数个数检查 */
|
/* 参数个数检查 */
|
||||||
if (lua_gettop(state) != 1)
|
if (lua_gettop(state) != 1)
|
||||||
@@ -553,14 +577,15 @@ int lua_session_get_id(lua_State * state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 参数类型检查 */
|
/* 参数类型检查 */
|
||||||
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA )
|
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct session * sess = (struct session *)lua_topointer(state, -1);
|
struct session *sess = (struct session *)lua_topointer(state, -1);
|
||||||
if ( !sess ) {
|
if (!sess)
|
||||||
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -570,7 +595,7 @@ int lua_session_get_id(lua_State * state)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_session_set_id(lua_State * state)
|
int lua_session_set_id(lua_State *state)
|
||||||
{
|
{
|
||||||
/* 参数个数检查 */
|
/* 参数个数检查 */
|
||||||
if (lua_gettop(state) != 2)
|
if (lua_gettop(state) != 2)
|
||||||
@@ -580,7 +605,7 @@ int lua_session_set_id(lua_State * state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 参数类型检查 */
|
/* 参数类型检查 */
|
||||||
if (lua_type(state, -1) != LUA_TNUMBER || lua_type(state, -2) != LUA_TLIGHTUSERDATA )
|
if (lua_type(state, -1) != LUA_TNUMBER || lua_type(state, -2) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -588,14 +613,14 @@ int lua_session_set_id(lua_State * state)
|
|||||||
|
|
||||||
int setid = lua_tointeger(state, -1);
|
int setid = lua_tointeger(state, -1);
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
struct session * sess = (struct session *)lua_topointer(state, -1);
|
struct session *sess = (struct session *)lua_topointer(state, -1);
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
|
|
||||||
session_set_id(sess, setid);
|
session_set_id(sess, setid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_session_get_type(lua_State * state)
|
int lua_session_get_type(lua_State *state)
|
||||||
{
|
{
|
||||||
/* 参数个数检查 */
|
/* 参数个数检查 */
|
||||||
if (lua_gettop(state) != 1)
|
if (lua_gettop(state) != 1)
|
||||||
@@ -605,14 +630,15 @@ int lua_session_get_type(lua_State * state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 参数类型检查 */
|
/* 参数类型检查 */
|
||||||
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA )
|
if (lua_type(state, -1) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct session * sess = (struct session *)lua_topointer(state, -1);
|
struct session *sess = (struct session *)lua_topointer(state, -1);
|
||||||
if ( !sess ) {
|
if (!sess)
|
||||||
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -622,7 +648,7 @@ int lua_session_get_type(lua_State * state)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_session_set_type(lua_State * state)
|
int lua_session_set_type(lua_State *state)
|
||||||
{
|
{
|
||||||
/* 参数个数检查 */
|
/* 参数个数检查 */
|
||||||
if (lua_gettop(state) != 2)
|
if (lua_gettop(state) != 2)
|
||||||
@@ -632,7 +658,7 @@ int lua_session_set_type(lua_State * state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 参数类型检查 */
|
/* 参数类型检查 */
|
||||||
if (lua_type(state, -1) != LUA_TNUMBER || lua_type(state, -2) != LUA_TLIGHTUSERDATA )
|
if (lua_type(state, -1) != LUA_TNUMBER || lua_type(state, -2) != LUA_TLIGHTUSERDATA)
|
||||||
{
|
{
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -640,7 +666,7 @@ int lua_session_set_type(lua_State * state)
|
|||||||
|
|
||||||
int settype = lua_tointeger(state, -1);
|
int settype = lua_tointeger(state, -1);
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
struct session * sess = (struct session *)lua_topointer(state, -1);
|
struct session *sess = (struct session *)lua_topointer(state, -1);
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
|
|
||||||
session_set_id(sess, settype);
|
session_set_id(sess, settype);
|
||||||
|
|||||||
@@ -30,22 +30,28 @@ void *lpm_ctx_new_func(
|
|||||||
{
|
{
|
||||||
if (__glibc_unlikely(!sess || !plugin_env))
|
if (__glibc_unlikely(!sess || !plugin_env))
|
||||||
return NULL;
|
return NULL;
|
||||||
struct lua_plugin_env *env = (struct lua_plugin_env *)plugin_env;
|
struct lua_model *env = (struct lua_model *)plugin_env;
|
||||||
|
|
||||||
/* 获取插件ID并找到该插件 */
|
/* 获取插件ID并找到该插件 */
|
||||||
int plugin_id = session_get_pluginid(sess);
|
int plugin_id = session_get_pluginid(sess);
|
||||||
// int plugin_id = 1;
|
// int plugin_id = 1;
|
||||||
struct lua_session_plugin *plugin = NULL;
|
struct lua_plugin *plugin = NULL;
|
||||||
while ((plugin = utarray_next(env->plugin_env_plugin_array, plugin)))
|
while ((plugin = utarray_next(env->plugin_array, plugin)))
|
||||||
{
|
{
|
||||||
if (plugin->plugin_id == plugin_id)
|
if (plugin->plugin_id == plugin_id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// LOGDEBUG("%d call plugin id %d, ref %d\n", plugin_id, plugin->plugin_id, plugin->ctx_new_ref);
|
||||||
if (!plugin || plugin->plugin_id != plugin_id)
|
if (!plugin || plugin->plugin_id != plugin_id)
|
||||||
/* 未找到该插件 */
|
/* 未找到该插件 */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct lua_context *new_context = lua_context_new(env->plugin_env_state);
|
/* 获取当前的线程id并找到该线程对应的state */
|
||||||
|
int thread_id = session_get_threadid(sess);
|
||||||
|
if ( thread_id > global_schema->state_count )
|
||||||
|
return NULL;
|
||||||
|
lua_State * state = global_schema->thread_state[thread_id - 1];
|
||||||
|
struct lua_context *new_context = lua_context_new(state);
|
||||||
if (__glibc_unlikely(!new_context))
|
if (__glibc_unlikely(!new_context))
|
||||||
/* 创建新的context失败 */
|
/* 创建新的context失败 */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -54,11 +60,11 @@ void *lpm_ctx_new_func(
|
|||||||
param[0].cdata_type = DATATYPE_POINTER;
|
param[0].cdata_type = DATATYPE_POINTER;
|
||||||
param[0].cdata_pointer = sess;
|
param[0].cdata_pointer = sess;
|
||||||
param[1].cdata_type = DATATYPE_TABLE;
|
param[1].cdata_type = DATATYPE_TABLE;
|
||||||
param[1].cdata_table = env->plugin_env_ref_id;
|
param[1].cdata_table = env->private_env_ref;
|
||||||
param[2].cdata_type = DATATYPE_CONTEXT;
|
param[2].cdata_type = DATATYPE_CONTEXT;
|
||||||
param[2].cdata_context = new_context;
|
param[2].cdata_context = new_context;
|
||||||
|
|
||||||
if (script_execute(&plugin->plugin_ctx_new_script, 3, param, 0, NULL))
|
if (lua_chunk_execute(state, plugin->ctx_new_ref, 3, param, 0, NULL))
|
||||||
{
|
{
|
||||||
/* 脚本执行失败 */
|
/* 脚本执行失败 */
|
||||||
free(new_context);
|
free(new_context);
|
||||||
@@ -85,13 +91,13 @@ void lpm_ctx_free_func(
|
|||||||
if (__glibc_unlikely(!sess || !sess_ctx || !plugin_env))
|
if (__glibc_unlikely(!sess || !sess_ctx || !plugin_env))
|
||||||
return;
|
return;
|
||||||
struct lua_context *context = (struct lua_context *)sess_ctx;
|
struct lua_context *context = (struct lua_context *)sess_ctx;
|
||||||
struct lua_plugin_env *env = (struct lua_plugin_env *)plugin_env;
|
struct lua_model *env = (struct lua_model *)plugin_env;
|
||||||
|
|
||||||
/* 获取插件ID并找到该插件 */
|
/* 获取插件ID并找到该插件 */
|
||||||
int plugin_id = session_get_pluginid(sess);
|
int plugin_id = session_get_pluginid(sess);
|
||||||
// int plugin_id = 1;
|
// int plugin_id = 1;
|
||||||
struct lua_session_plugin *plugin = NULL;
|
struct lua_plugin *plugin = NULL;
|
||||||
while ((plugin = utarray_next(env->plugin_env_plugin_array, plugin)))
|
while ((plugin = utarray_next(env->plugin_array, plugin)))
|
||||||
{
|
{
|
||||||
if (plugin->plugin_id == plugin_id)
|
if (plugin->plugin_id == plugin_id)
|
||||||
break;
|
break;
|
||||||
@@ -100,16 +106,21 @@ void lpm_ctx_free_func(
|
|||||||
/* 未找到该插件 */
|
/* 未找到该插件 */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
int thread_id = session_get_threadid(sess);
|
||||||
|
if ( thread_id > global_schema->state_count )
|
||||||
|
return;
|
||||||
|
lua_State * state = global_schema->thread_state[thread_id];
|
||||||
|
|
||||||
struct lua_cdata param[3] = {0};
|
struct lua_cdata param[3] = {0};
|
||||||
param[0].cdata_type = DATATYPE_POINTER;
|
param[0].cdata_type = DATATYPE_POINTER;
|
||||||
param[0].cdata_pointer = sess;
|
param[0].cdata_pointer = sess;
|
||||||
param[1].cdata_type = DATATYPE_CONTEXT;
|
param[1].cdata_type = DATATYPE_CONTEXT;
|
||||||
param[1].cdata_context = context;
|
param[1].cdata_context = context;
|
||||||
param[2].cdata_type = DATATYPE_TABLE;
|
param[2].cdata_type = DATATYPE_TABLE;
|
||||||
param[2].cdata_table = env->plugin_env_ref_id;
|
param[2].cdata_table = env->private_env_ref;
|
||||||
|
|
||||||
script_execute(&plugin->plugin_ctx_free_script, 3, param, 0, NULL);
|
lua_chunk_execute(state, plugin->ctx_free_ref, 3, param, 0, NULL);
|
||||||
lua_context_free(context);
|
lua_context_free(state, context);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
* struct lua_context * lua_context_new;
|
* struct lua_context * lua_context_new;
|
||||||
* int lua_context_push_stack;
|
* int lua_context_push_stack;
|
||||||
* void lua_context_free;
|
* void lua_context_free;
|
||||||
|
*
|
||||||
|
* 08-12
|
||||||
|
* 1. 修改部分函数返回值, 使用统一的错误码, 方便统一处理
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include "lua_plugin_manage_internal.h"
|
#include "lua_plugin_manage_internal.h"
|
||||||
|
|
||||||
@@ -24,9 +27,7 @@
|
|||||||
* Input: | lua_State * | state | 入栈数据使用的状态机
|
* Input: | lua_State * | state | 入栈数据使用的状态机
|
||||||
* | struct lua_cdata * | cdata | 需要入栈的数据
|
* | struct lua_cdata * | cdata | 需要入栈的数据
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | -1 | 参数错误
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | 1 | 入栈数据类型有误
|
|
||||||
* | 0 | 入栈成功
|
|
||||||
* Description: 将一个数据元素入栈
|
* Description: 将一个数据元素入栈
|
||||||
*/
|
*/
|
||||||
int lua_cdata_push_stack(
|
int lua_cdata_push_stack(
|
||||||
@@ -34,39 +35,42 @@ int lua_cdata_push_stack(
|
|||||||
struct lua_cdata *cdata)
|
struct lua_cdata *cdata)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !cdata))
|
if (__glibc_unlikely(!state || !cdata))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
|
||||||
switch (cdata->cdata_type)
|
switch (cdata->cdata_type)
|
||||||
{
|
{
|
||||||
|
/* 不同的数据类型入栈方式不同 */
|
||||||
case DATATYPE_NIL:
|
case DATATYPE_NIL:
|
||||||
lua_pushnil(state);
|
lua_pushnil(state);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_BOOL:
|
case DATATYPE_BOOL:
|
||||||
lua_pushboolean(state, cdata->cdata_bool);
|
lua_pushboolean(state, cdata->cdata_bool);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_INT:
|
case DATATYPE_INT:
|
||||||
lua_pushinteger(state, cdata->cdata_int);
|
lua_pushinteger(state, cdata->cdata_int);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_NUM:
|
case DATATYPE_NUM:
|
||||||
lua_pushnumber(state, cdata->cdata_num);
|
lua_pushnumber(state, cdata->cdata_num);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_STRING:
|
case DATATYPE_STRING:
|
||||||
lua_pushstring(state, cdata->cdata_string);
|
if (lua_pushstring(state, cdata->cdata_string) == NULL)
|
||||||
return 0;
|
return DATA_PUSHSTACK_ERR;
|
||||||
|
return SUCCESS;
|
||||||
case DATATYPE_TABLE:
|
case DATATYPE_TABLE:
|
||||||
lua_rawgeti(state, LUA_REGISTRYINDEX, cdata->cdata_table);
|
lua_rawgeti(state, LUA_REGISTRYINDEX, cdata->cdata_table);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_POINTER:
|
case DATATYPE_POINTER:
|
||||||
lua_pushlightuserdata(state, (void *)cdata->cdata_pointer);
|
lua_pushlightuserdata(state, (void *)cdata->cdata_pointer);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
case DATATYPE_CONTEXT:
|
case DATATYPE_CONTEXT:
|
||||||
lua_context_push_stack(cdata->cdata_context);
|
if (lua_context_push_stack(state, cdata->cdata_context))
|
||||||
return 0;
|
return DATA_PUSHSTACK_ERR;
|
||||||
|
return SUCCESS;
|
||||||
default:
|
default:
|
||||||
LOGERROR("can't recorgnize data type %d", cdata->cdata_type);
|
LOGERROR("can't recorgnize data type %d", cdata->cdata_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return DATA_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -74,9 +78,7 @@ int lua_cdata_push_stack(
|
|||||||
* Input: | lua_State * | state | 出栈数据使用的状态机
|
* Input: | lua_State * | state | 出栈数据使用的状态机
|
||||||
* | struct lua_cdata * | cdata | 保存出栈的元素
|
* | struct lua_cdata * | cdata | 保存出栈的元素
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | -1 | 参数错误
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -2 | 出栈数据类型有误
|
|
||||||
* | 0 | 出栈成功
|
|
||||||
* Description: 将一个数据元素出栈, 出栈过程中无法出栈context与table类型
|
* Description: 将一个数据元素出栈, 出栈过程中无法出栈context与table类型
|
||||||
* TODO: 扩展类型, 支持更多数据类型
|
* TODO: 扩展类型, 支持更多数据类型
|
||||||
*/
|
*/
|
||||||
@@ -85,9 +87,9 @@ int lua_cdata_pop_stack(
|
|||||||
struct lua_cdata *cdata)
|
struct lua_cdata *cdata)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!state || !cdata))
|
if (__glibc_unlikely(!state || !cdata))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
if (!lua_gettop(state))
|
if (!lua_gettop(state))
|
||||||
return 0;
|
return DATA_POPSTACK_NODATA;
|
||||||
|
|
||||||
switch (lua_type(state, -1))
|
switch (lua_type(state, -1))
|
||||||
{
|
{
|
||||||
@@ -117,13 +119,13 @@ int lua_cdata_pop_stack(
|
|||||||
cdata->cdata_pointer = (void *)lua_topointer(state, -1);
|
cdata->cdata_pointer = (void *)lua_topointer(state, -1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* 其他数据类型之后处理 */
|
/* TODO: 其他数据类型之后处理 */
|
||||||
LOGERROR("other lua type can't pop out, %d", lua_type(state, -1));
|
LOGERROR("other lua type can't pop out, %d", lua_type(state, -1));
|
||||||
return -2;
|
return DATA_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pop(state, 1);
|
lua_pop(state, 1);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -140,7 +142,6 @@ void lua_cdata_destory(struct lua_cdata *cdata)
|
|||||||
return;
|
return;
|
||||||
if (cdata->cdata_type == DATATYPE_STRING && cdata->cdata_string)
|
if (cdata->cdata_type == DATATYPE_STRING && cdata->cdata_string)
|
||||||
free(cdata->cdata_string);
|
free(cdata->cdata_string);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,11 +160,12 @@ struct lua_context *lua_context_new(lua_State *state)
|
|||||||
|
|
||||||
lua_newtable(state);
|
lua_newtable(state);
|
||||||
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||||
|
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
||||||
|
LOGDEBUG("create new context, ref id is %d\n", ref_id);
|
||||||
|
#endif
|
||||||
lua_settop(state, 0);
|
lua_settop(state, 0);
|
||||||
if (ref_id == LUA_REFNIL)
|
if (ref_id == LUA_REFNIL)
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context));
|
struct lua_context *new_context = (struct lua_context *)calloc(1, sizeof(struct lua_context));
|
||||||
if (__glibc_unlikely(!new_context))
|
if (__glibc_unlikely(!new_context))
|
||||||
@@ -171,40 +173,42 @@ struct lua_context *lua_context_new(lua_State *state)
|
|||||||
luaL_unref(state, LUA_REGISTRYINDEX, ref_id);
|
luaL_unref(state, LUA_REGISTRYINDEX, ref_id);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
new_context->context_state = state;
|
// new_context->context_state = state;
|
||||||
new_context->context_ref_id = ref_id;
|
new_context->context_ref_id = ref_id;
|
||||||
return new_context;
|
return new_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: lua_context_push_stack
|
* Function: lua_context_push_stack
|
||||||
* Input: | struct lua_context * | context | 待入栈的context结构
|
* Input: | lua_State * | state | 将该context入栈
|
||||||
|
* | struct lua_context * | context | 待入栈的context结构
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | 0 | 入栈成功
|
* Return: | 0 | 入栈成功
|
||||||
* | -1 | 参数错误
|
* | -1 | 参数错误
|
||||||
* Description: 将一个context入栈, 实际入栈流程与table一致
|
* Description: 将一个context入栈, 实际入栈流程与table一致
|
||||||
*/
|
*/
|
||||||
int lua_context_push_stack(struct lua_context *context)
|
int lua_context_push_stack(lua_State *state, struct lua_context *context)
|
||||||
{
|
{
|
||||||
if (luai_unlikely(!context))
|
if (luai_unlikely(!state || !context))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
|
|
||||||
lua_rawgeti(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
lua_rawgeti(state, LUA_REGISTRYINDEX, context->context_ref_id);
|
||||||
return 0;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: lua_context_free
|
* Function: lua_context_free
|
||||||
* Input: | struct lua_context * | context | 释放一个context
|
* Input: | lua_State * | state | 在该状态机中删除context
|
||||||
|
* | struct lua_context * | context | 释放一个context
|
||||||
* Output:
|
* Output:
|
||||||
* Return:
|
* Return:
|
||||||
* Description: 释放一个context
|
* Description: 释放一个context
|
||||||
*/
|
*/
|
||||||
void lua_context_free(struct lua_context *context)
|
void lua_context_free(lua_State *state, struct lua_context *context)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!context))
|
if (__glibc_unlikely(!state || !context))
|
||||||
return;
|
return;
|
||||||
luaL_unref(context->context_state, LUA_REGISTRYINDEX, context->context_ref_id);
|
luaL_unref(state, LUA_REGISTRYINDEX, context->context_ref_id);
|
||||||
free(context);
|
free(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -31,663 +31,205 @@
|
|||||||
* int script_execute;
|
* int script_execute;
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include "lua_plugin_manage_internal.h"
|
#include "lua_plugin_manage_internal.h"
|
||||||
#include "lpm_log.h"
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <toml.h>
|
struct lua_plugin_manage_schema * global_schema = NULL;
|
||||||
|
|
||||||
static UT_icd specific_icd = {sizeof(struct lua_config_specific), NULL, specific_instance_copy, specific_instance_destory};
|
|
||||||
static UT_icd session_plugin_icd = {sizeof(struct lua_session_plugin), NULL, NULL, session_plugin_instance_destory};
|
|
||||||
static UT_icd plugin_env_icd = {sizeof(struct lua_plugin_env), NULL, NULL, plugin_env_instance_destory};
|
|
||||||
static UT_icd thread_state_icd = {sizeof(struct lua_thread_state), NULL, NULL, thread_state_instance_destory};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: specific_instance_copy
|
* Function: thread_state_init
|
||||||
* Input: | void * | dst | 拷贝数据目的地址
|
* Input: | int | thread_id | 创建状态机的线程号
|
||||||
* | void * | src | 拷贝数据源地址
|
|
||||||
* Output:
|
* Output:
|
||||||
* Return:
|
* Return: 创建完成的状态机实例指针
|
||||||
* Description: 配置的插件信息拷贝函数, 由于可能存在多线程, 将数据完整拷贝一次
|
* Description: 创建一个lua的状态机实例, 在每个线程中创建一个
|
||||||
*/
|
*/
|
||||||
void specific_instance_copy(void *dst, const void *src)
|
lua_State *thread_state_init(int thread_id)
|
||||||
{
|
{
|
||||||
struct lua_config_specific *dst_spec = (struct lua_config_specific *)dst;
|
|
||||||
struct lua_config_specific *src_spec = (struct lua_config_specific *)src;
|
|
||||||
if (__glibc_unlikely(!dst_spec || !src_spec))
|
|
||||||
return;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: specific_instance_destory
|
|
||||||
* Input: | void * | elt | 待销毁的specific实例
|
|
||||||
* Output:
|
|
||||||
* Return:
|
|
||||||
* Description: 销毁一个specific实例, 并释放内部占用的内存
|
|
||||||
*/
|
|
||||||
void specific_instance_destory(void *elt)
|
|
||||||
{
|
|
||||||
struct lua_config_specific *element = (struct lua_config_specific *)elt;
|
|
||||||
if (!element)
|
|
||||||
return;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: script_instance_init_byname
|
|
||||||
* Input: | struct lua_script * | script | 需要进行初始化的脚本结构
|
|
||||||
* | lua_State * | state | 脚本注册使用的状态机
|
|
||||||
* | const char * | filepath | 脚本加载的文件路径
|
|
||||||
* | const char * | funcname | 脚本加载的函数名称
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 加载成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -3 | 状态机读取文件失败
|
|
||||||
* | -4 | 状态机加载文件后运行失败
|
|
||||||
* | -5 | 加载函数过程中未找到该函数
|
|
||||||
* | -6 | 创建函数引用ID失败
|
|
||||||
* Description: 将一个lua文件中的函数创建成一个lua_script结构, 方便调用运行
|
|
||||||
*/
|
|
||||||
int script_instance_init_byname(
|
|
||||||
struct lua_script *script,
|
|
||||||
lua_State *state,
|
|
||||||
const char *filepath,
|
|
||||||
const char *funcname)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!script || !state || !filepath || !funcname))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* 在加载配置文件的时候检查过了, 这里不检查 */
|
|
||||||
if (access(filepath, F_OK))
|
|
||||||
/* 文件不存在 */
|
|
||||||
return -2;
|
|
||||||
#endif
|
|
||||||
if (luaL_loadfile(state, filepath))
|
|
||||||
/* 加载文件失败 */
|
|
||||||
return -3;
|
|
||||||
/* 仅加载不运行 */
|
|
||||||
// lua_settop(state, 0);
|
|
||||||
/* Bugfix: 这里还是需要运行一次, 否则可能加载不完整 */
|
|
||||||
if (lua_pcall(state, 0, 0, 0))
|
|
||||||
{
|
|
||||||
/* 文件加载完成后检查存在错误 */
|
|
||||||
lua_settop(state, 0);
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
lua_settop(state, 0);
|
|
||||||
|
|
||||||
/* 加载全局变量, 找到函数后进行类型判断 */
|
|
||||||
lua_getglobal(state, funcname);
|
|
||||||
if (lua_type(state, -1) != LUA_TFUNCTION)
|
|
||||||
{
|
|
||||||
/* 在已经加载的文件中未找到对应的函数名称 */
|
|
||||||
lua_settop(state, 0);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
/* 创建索引 */
|
|
||||||
int ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
|
||||||
if (ref_id == LUA_REFNIL)
|
|
||||||
{
|
|
||||||
/* 索引创建失败 */
|
|
||||||
lua_settop(state, 0);
|
|
||||||
return -6;
|
|
||||||
}
|
|
||||||
|
|
||||||
script_instance_init_byrefid(script, state, ref_id);
|
|
||||||
lua_settop(state, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: script_instance_init_byrefid
|
|
||||||
* Input: | struct lua_script * | script | 需要进行初始化的脚本结构
|
|
||||||
* | lua_State * | state | 脚本注册使用的状态机
|
|
||||||
* | int | ref_id | 代码已经在状态机中生成的refid
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 初始化成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* Description: 根据已经生成的refid初始化一个脚本结构实例
|
|
||||||
*/
|
|
||||||
int script_instance_init_byrefid(
|
|
||||||
struct lua_script *script,
|
|
||||||
lua_State *state,
|
|
||||||
int ref_id)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!script || !state || ref_id == LUA_REFNIL))
|
|
||||||
return -1;
|
|
||||||
script->script_state = state;
|
|
||||||
script->script_ref_id = ref_id;
|
|
||||||
script->script_run_success = 0;
|
|
||||||
script->script_run_failed = 0;
|
|
||||||
script->script_total_ms = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: script_instance_clean
|
|
||||||
* Input: | struct lua_script * | script | 需要清理的脚本实例
|
|
||||||
* Output:
|
|
||||||
* Return:
|
|
||||||
* Description: 清理一个脚本, 并在状态机中释放该脚本的引用
|
|
||||||
*/
|
|
||||||
void script_instance_clean(struct lua_script *script)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!script))
|
|
||||||
return;
|
|
||||||
|
|
||||||
lua_State *state = script->script_state;
|
|
||||||
luaL_unref(state, LUA_REGISTRYINDEX, script->script_ref_id);
|
|
||||||
lua_settop(state, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: script_execute
|
|
||||||
* Input: | struct lua_script * | script | 需要执行的lua脚本
|
|
||||||
* | int | pcount | 传入的参数个数
|
|
||||||
* | struct lua_cdata * | param | 传入的参数值
|
|
||||||
* | int | rmaxcount | 最大可接收的返回值个数
|
|
||||||
* | struct lua_cdata * | rvalue | 接收返回值的data结构
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 脚本执行成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 无法获取脚本调用的lua函数
|
|
||||||
* | -3 | 参数无法入栈
|
|
||||||
* | -4 | 函数执行过程中出错
|
|
||||||
* | -5 | 返回值出栈过程中数量过多
|
|
||||||
* | -6 | 返回值出栈失败
|
|
||||||
* Description: 调用并执行一个lua脚本
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: session_plugin_instance_init
|
|
||||||
* Input: | struct lua_session_plugin * | session_plugin | 需要进行初始化的插件实例
|
|
||||||
* | lua_State * | state | 插件注册使用的状态机
|
|
||||||
* | int | plugin_id | 插件注册完成后得到的插件编号
|
|
||||||
* | int | new_refid | ctx_new函数在状态机中的引用
|
|
||||||
* | int | free_refid | ctx_free函数在状态机中的引用
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 初始化成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* Description: 初始化一个插件实例
|
|
||||||
*/
|
|
||||||
int session_plugin_instance_init(
|
|
||||||
struct lua_session_plugin *session_plugin,
|
|
||||||
lua_State *state,
|
|
||||||
int plugin_id,
|
|
||||||
int new_refid,
|
|
||||||
int free_refid)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!session_plugin || !state))
|
|
||||||
return -1;
|
|
||||||
session_plugin->plugin_id = plugin_id;
|
|
||||||
script_instance_init_byrefid(&session_plugin->plugin_ctx_new_script, state, new_refid);
|
|
||||||
script_instance_init_byrefid(&session_plugin->plugin_ctx_free_script, state, free_refid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: session_plugin_instance_destory
|
|
||||||
* Input: | void * | elt | 待销毁的插件实例
|
|
||||||
* Output:
|
|
||||||
* Return:
|
|
||||||
* Description: 销毁一个插件实例, 并将插件中引用的函数在状态机中释放
|
|
||||||
*/
|
|
||||||
void session_plugin_instance_destory(void *elt)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!elt))
|
|
||||||
return;
|
|
||||||
struct lua_session_plugin *session_plugin = (struct lua_session_plugin *)elt;
|
|
||||||
script_instance_clean(&session_plugin->plugin_ctx_new_script);
|
|
||||||
script_instance_clean(&session_plugin->plugin_ctx_free_script);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: plugin_env_instance_init
|
|
||||||
* Input: | struct lua_plugin_env * | plugin_env | 插件的运行环境实例
|
|
||||||
* | lua_State * | state | 插件注册的状态机
|
|
||||||
* | struct lua_config_specific * | specific | 插件需要加载的配置实例
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 初始化成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 加载函数加载错误
|
|
||||||
* | -3 | 卸载函数加载错误
|
|
||||||
* | -4 | 创建全局函数变量失败
|
|
||||||
* Description: 初始化一个插件的运行环境变量
|
|
||||||
*/
|
|
||||||
int plugin_env_instance_init(
|
|
||||||
struct lua_plugin_env *plugin_env,
|
|
||||||
lua_State *state,
|
|
||||||
struct lua_config_specific *specific)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!plugin_env || !state || !specific))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(plugin_env, 0, sizeof(struct lua_plugin_env));
|
|
||||||
plugin_env->plugin_env_state = state;
|
|
||||||
plugin_env->plugin_env_plugin_array = NULL;
|
|
||||||
plugin_env->plugin_env_filepath = strdup(specific->config_specific_file);
|
|
||||||
// plugin_env->plugin_env_name = strdup(specific->config_specific_name);
|
|
||||||
/* 从文件中加载load函数, 但此时不调用 */
|
|
||||||
if (script_instance_init_byname(&plugin_env->plugin_env_load_func,
|
|
||||||
state,
|
|
||||||
specific->config_specific_file,
|
|
||||||
specific->config_specific_load_func))
|
|
||||||
{
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
/* 从文件中加载unload函数 */
|
|
||||||
if (script_instance_init_byname(&plugin_env->plugin_env_unload_func,
|
|
||||||
state,
|
|
||||||
specific->config_specific_file,
|
|
||||||
specific->config_specific_unload_func))
|
|
||||||
{
|
|
||||||
script_instance_clean(&plugin_env->plugin_env_load_func);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
/* 创建私有数据空间 */
|
|
||||||
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->plugin_env_ref_id = ref_id;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: plugin_env_instance_destory
|
|
||||||
* Input: | void * | elt | 待销毁的插件运行环境实例
|
|
||||||
* Output:
|
|
||||||
* Return:
|
|
||||||
* Description: 销毁一个插件运行环境实例, 并在状态机中释放其引用
|
|
||||||
*/
|
|
||||||
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->plugin_env_plugin_array)
|
|
||||||
utarray_free(plugin_env->plugin_env_plugin_array);
|
|
||||||
if (plugin_env->plugin_env_filepath)
|
|
||||||
free(plugin_env->plugin_env_filepath);
|
|
||||||
|
|
||||||
/* 释放插件的加载函数与卸载函数 */
|
|
||||||
script_instance_clean(&plugin_env->plugin_env_load_func);
|
|
||||||
script_instance_clean(&plugin_env->plugin_env_unload_func);
|
|
||||||
|
|
||||||
/* 将lua中的私有环境数据取消引用 */
|
|
||||||
if (plugin_env->plugin_env_ref_id)
|
|
||||||
luaL_unref(plugin_env->plugin_env_state, LUA_REGISTRYINDEX, plugin_env->plugin_env_ref_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: thread_state_instance_init
|
|
||||||
* Input: | struct lua_thread_state * | thread_state | 待初始化的线程状态机
|
|
||||||
* | int | state_id | 线程的ID号
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 初始化成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 创建新的状态机失败
|
|
||||||
* Description: 在线程中创建一个状态机, 并进行初始化
|
|
||||||
*/
|
|
||||||
int thread_state_instance_init(
|
|
||||||
struct lua_thread_state *thread_state,
|
|
||||||
int state_id)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!thread_state))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
lua_State *new_state = luaL_newstate();
|
lua_State *new_state = luaL_newstate();
|
||||||
if (__glibc_unlikely(!new_state))
|
if (__glibc_unlikely(!new_state))
|
||||||
return -2;
|
return NULL;
|
||||||
|
|
||||||
luaL_openlibs(new_state);
|
luaL_openlibs(new_state);
|
||||||
/* 绑定所有注册函数 */
|
/* 绑定所有注册函数 */
|
||||||
lua_cbinding_functions(new_state);
|
lua_cbinding_functions(new_state);
|
||||||
/* 绑定所有全局变量 */
|
/* 绑定所有全局变量 */
|
||||||
lua_cbinding_datas(new_state);
|
lua_cbinding_datas(new_state);
|
||||||
|
|
||||||
|
lua_pushinteger(new_state, thread_id);
|
||||||
|
lua_setglobal(new_state, LUA_STATE_THREAD_ID_KEY);
|
||||||
|
|
||||||
lua_settop(new_state, 0);
|
lua_settop(new_state, 0);
|
||||||
|
|
||||||
memset(thread_state, 0, sizeof(struct lua_thread_state));
|
return new_state;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: thread_state_instance_destory
|
* Function: thread_state_load_specific
|
||||||
* Input: | void * | elt | 待销毁的状态机
|
* Input: | lua_State * | state | 进行初始化的状态机
|
||||||
|
* | struct lua_model * | model | 需要加载的模块, 模块数量与具体配置实例的数量一致
|
||||||
|
* | struct lua_config_specific * | specific | 加载的配置
|
||||||
* Output:
|
* Output:
|
||||||
* Return:
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* Description: 销毁一个线程状态机
|
* Description: 在状态机中加载一个具体配置, 并将加载完成后生成的引用值保存在model中, 加载过程中会使用model进行校验
|
||||||
*/
|
*/
|
||||||
void thread_state_instance_destory(void *elt)
|
int thread_state_load_specific(
|
||||||
|
lua_State *state,
|
||||||
|
struct lua_model *model,
|
||||||
|
struct lua_config_specific *specific)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!elt))
|
if (__glibc_unlikely(!state || !model || !specific))
|
||||||
return;
|
return PARAM_ERR;
|
||||||
struct lua_thread_state *thread_state = (struct lua_thread_state *)elt;
|
if (__glibc_unlikely(!specific->config_specific_file || !specific->config_specific_load_func || !specific->config_specific_unload_func))
|
||||||
/* 卸载所有已经注册的插件 */
|
return PARAM_ERR;
|
||||||
if (thread_state->thread_env_array)
|
|
||||||
utarray_free(thread_state->thread_env_array);
|
|
||||||
/* 关闭状态机 */
|
|
||||||
if (thread_state->thread_state)
|
|
||||||
lua_close(thread_state->thread_state);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: thread_state_instance_load
|
|
||||||
* Input: | struct lua_thread_state * | thread_state | 进行初始化加载的状态机
|
|
||||||
* | struct lua_plugin_manage_schema * | schema | 已经完成配置读取的全局实例
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 加载成功
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 根据加载的配置初始化插件失败
|
|
||||||
* Description: 在线程的状态机中依次加载插件
|
|
||||||
*/
|
|
||||||
int thread_state_instance_load(
|
|
||||||
struct lua_thread_state *thread_state,
|
|
||||||
struct lua_plugin_manage_schema *schema)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!thread_state || !schema))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* 读取所有插件并加入插件列表中 */
|
|
||||||
struct lua_plugin_env new_plugin_env;
|
|
||||||
while ((specific = utarray_next(schema->lua_config_specific_array, specific)))
|
|
||||||
{
|
|
||||||
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->thread_env_array, &new_plugin_env);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 依次执行插件加载函数, 调用lua中load函数 */
|
|
||||||
struct lua_plugin_env *plugin_env = NULL;
|
|
||||||
while ((plugin_env = utarray_next(thread_state->thread_env_array, plugin_env)))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
luaL_loadfile(state, plugin_env->plugin_env_filepath);
|
|
||||||
lua_pcall(state, 0, 0, 0);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: specific_check
|
|
||||||
* Input: | struct lua_config_specific * | specific | 待减产的配置项
|
|
||||||
* Output:
|
|
||||||
* Return: | 0 | 检查无问题
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 配置中的插件文件不存在
|
|
||||||
* Description: 检查配置是否有明显问题
|
|
||||||
* TODO: 目前仅检查文件是否存在, 后续逐步补充, 比如文件内是否有不应该使用的函数等
|
|
||||||
*/
|
|
||||||
static int specific_check(struct lua_config_specific *specific)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!specific))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
|
/* 加载lua文件 */
|
||||||
if (access(specific->config_specific_file, F_OK))
|
if (access(specific->config_specific_file, F_OK))
|
||||||
return -2;
|
return STATE_LOAD_FILE_ERR;
|
||||||
|
if (luaL_loadfile(state, specific->config_specific_file))
|
||||||
|
return STATE_LOAD_FILE_ERR;
|
||||||
|
if (lua_pcall(state, 0, 0, 0))
|
||||||
|
{
|
||||||
|
LOGERROR("load specific failed, file is %s, err is %s", specific->config_specific_file, lua_tostring(state, -1));
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return STATE_LOAD_FILE_ERR;
|
||||||
|
}
|
||||||
|
lua_settop(state, 0);
|
||||||
|
|
||||||
return 0;
|
/* 创建plugin_env */
|
||||||
|
lua_newtable(state);
|
||||||
|
int env_ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||||
|
if (env_ref_id == LUA_REFNIL)
|
||||||
|
return STATE_CREATE_ENV_FAIL;
|
||||||
|
if ((model->model_mark & MODEL_MARK_INIT_DONE) && (model->private_env_ref != env_ref_id))
|
||||||
|
{
|
||||||
|
LOGERROR("load new model, create plugin env id is not same, %d, %d", model->private_env_ref, env_ref_id);
|
||||||
|
return STATE_CREATE_ENV_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载load函数 */
|
||||||
|
lua_getglobal(state, specific->config_specific_load_func);
|
||||||
|
if (lua_type(state, -1) != LUA_TFUNCTION)
|
||||||
|
{
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, env_ref_id);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return STATE_GET_LOAD_FAIL;
|
||||||
|
}
|
||||||
|
int load_ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||||
|
if (load_ref_id == LUA_REFNIL)
|
||||||
|
{
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, env_ref_id);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return STATE_GET_LOAD_FAIL;
|
||||||
|
}
|
||||||
|
if ((model->model_mark & MODEL_MARK_INIT_DONE) && (model->load_ref != load_ref_id))
|
||||||
|
{
|
||||||
|
LOGERROR("load new model, load ref id is not same, %d, %d", model->load_ref, load_ref_id);
|
||||||
|
return STATE_GET_LOAD_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载unload函数 */
|
||||||
|
lua_getglobal(state, specific->config_specific_unload_func);
|
||||||
|
if (lua_type(state, -1) != LUA_TFUNCTION)
|
||||||
|
{
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, env_ref_id);
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, load_ref_id);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return STATE_GET_UNLOAD_FAIL;
|
||||||
|
}
|
||||||
|
int unload_ref_id = luaL_ref(state, LUA_REGISTRYINDEX);
|
||||||
|
if (unload_ref_id == LUA_REFNIL)
|
||||||
|
{
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, env_ref_id);
|
||||||
|
luaL_unref(state, LUA_REGISTRYINDEX, load_ref_id);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return STATE_GET_UNLOAD_FAIL;
|
||||||
|
}
|
||||||
|
if ((model->model_mark & MODEL_MARK_INIT_DONE) && (model->unload_ref != unload_ref_id))
|
||||||
|
{
|
||||||
|
LOGERROR("load new model, unload ref id is not same, %d, %d", model->unload_ref, unload_ref_id);
|
||||||
|
return STATE_GET_UNLOAD_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 首次加载时完成model初始化 */
|
||||||
|
if (!(model->model_mark & MODEL_MARK_INIT_DONE))
|
||||||
|
{
|
||||||
|
model->private_env_ref = env_ref_id;
|
||||||
|
model->load_ref = load_ref_id;
|
||||||
|
model->unload_ref = unload_ref_id;
|
||||||
|
model->model_mark |= MODEL_MARK_INIT_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(state, 0);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UT_icd lua_plugin_icd = {sizeof(struct lua_plugin), NULL, NULL, NULL};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: thread_state_call_load
|
||||||
|
* Input: | lua_State * | state | 进行模块加载的状态机
|
||||||
|
* | struct lua_model * | model | 需要进行加载的lua模块
|
||||||
|
* | struct lua_config_specific * | specific | 加载模块的配置信息
|
||||||
|
* | struct stellar * | st | 与C插件管理保持一致, stellar作为参数传入
|
||||||
|
* Output:
|
||||||
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
|
* Description: 在状态机中调用一个模块的load函数, 在状态机中完成该模块的加载
|
||||||
|
*/
|
||||||
|
int thread_state_call_load(
|
||||||
|
lua_State *state,
|
||||||
|
struct lua_model *model,
|
||||||
|
struct lua_config_specific *specific,
|
||||||
|
struct stellar *st)
|
||||||
|
{
|
||||||
|
if (__glibc_unlikely(!state || !model || !specific || !st))
|
||||||
|
return PARAM_ERR;
|
||||||
|
|
||||||
|
if ((!(model->model_mark & MODEL_MARK_LOAD_DONE)) && (!model->plugin_array))
|
||||||
|
{
|
||||||
|
utarray_new(model->plugin_array, &lua_plugin_icd);
|
||||||
|
model->model_mark |= MODEL_MARK_LOAD_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(state, LUA_REGISTRYINDEX, model->private_env_ref);
|
||||||
|
lua_pushlightuserdata(state, model);
|
||||||
|
/* 在该状态机对应模块的plugin_env中创建该结构对应的指针 */
|
||||||
|
lua_setfield(state, -2, LUA_PLUGIN_ENV_DEFAULT_KEY);
|
||||||
|
lua_settop(state, 0);
|
||||||
|
luaL_loadfile(state, specific->config_specific_file);
|
||||||
|
lua_pcall(state, 0, 0, 0);
|
||||||
|
|
||||||
|
struct lua_cdata params[2];
|
||||||
|
params[0].cdata_type = DATATYPE_POINTER;
|
||||||
|
params[0].cdata_pointer = st;
|
||||||
|
params[1].cdata_type = DATATYPE_TABLE;
|
||||||
|
params[1].cdata_table = model->private_env_ref;
|
||||||
|
|
||||||
|
return lua_chunk_execute(state, model->load_ref, 2, params, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function: lua_plugin_manage_config_load
|
* Function: thread_state_call_unload
|
||||||
* Input: | struct lua_plugin_manage_schema * | scheme | 加载插件的全局变量
|
* Input: | lua_State * | 卸载模块的状态机
|
||||||
* | const char * | config_file_name | 插件配置文件
|
* | struct lua_model * | 需要卸载的模块
|
||||||
* Output:
|
* Output:
|
||||||
* Return: | >=0 | 加载成功, 返回读取的配置插件数量
|
* Return: enum LUA_PLUGIN_RETURN
|
||||||
* | -1 | 参数错误
|
* Description: 在一个状态机中对某模块调用其卸载unload函数
|
||||||
* | -2 | 配置文件不存在或打开文件错误
|
|
||||||
* | -3 | toml加载失败
|
|
||||||
* | -4 | 获取插件列表失败
|
|
||||||
* | -5 | 插件配置项错误
|
|
||||||
* | -6 | 插件配置检查出现问题
|
|
||||||
* Description: 从配置文件中读取所有插件配置
|
|
||||||
*/
|
*/
|
||||||
int lua_plugin_manage_config_load(
|
int thread_state_call_unload(
|
||||||
struct lua_plugin_manage_schema *schema,
|
lua_State *state,
|
||||||
const char *config_file_name)
|
struct lua_model *model)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!schema || !config_file_name))
|
if (__glibc_unlikely(!state || !model))
|
||||||
return -1;
|
return PARAM_ERR;
|
||||||
int specific_num = 0;
|
|
||||||
char errbuff[256] = {0};
|
|
||||||
|
|
||||||
if (access(config_file_name, F_OK))
|
struct lua_cdata param;
|
||||||
return -2;
|
param.cdata_type = DATATYPE_TABLE;
|
||||||
FILE *fp = fopen(config_file_name, "r");
|
param.cdata_table = model->private_env_ref;
|
||||||
if (!fp)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
toml_table_t *conf = toml_parse_file(fp, errbuff, sizeof(errbuff));
|
return lua_chunk_execute(state, model->unload_ref, 1, ¶m, 0, NULL);
|
||||||
if (fp)
|
|
||||||
fclose(fp);
|
|
||||||
if (!conf)
|
|
||||||
{
|
|
||||||
LOGERROR("parse config file failed, filename %s, err %s\n", config_file_name, errbuff);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
toml_array_t *plugin_array = toml_array_in(conf, "plugin");
|
|
||||||
if (!plugin_array)
|
|
||||||
return -4;
|
|
||||||
|
|
||||||
/* 获取配置中配置的插件数量 */
|
|
||||||
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(1, sizeof(struct lua_config_specific));
|
|
||||||
|
|
||||||
for (int i = 0; i < specific_num; ++i)
|
|
||||||
{
|
|
||||||
toml_table_t *plugin = toml_table_at(plugin_array, i);
|
|
||||||
const char *raw_filepath = toml_raw_in(plugin, "path");
|
|
||||||
// const char *raw_name = toml_raw_in(plugin, "name");
|
|
||||||
const char *raw_load_func_name = toml_raw_in(plugin, "init");
|
|
||||||
const char *raw_unload_func_name = toml_raw_in(plugin, "exit");
|
|
||||||
|
|
||||||
/* 从配置中拷贝字符串到specific实例中 */
|
|
||||||
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);
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 插件配置检查 */
|
|
||||||
int spec_check_ret = specific_check(specific);
|
|
||||||
if (spec_check_ret)
|
|
||||||
{
|
|
||||||
LOGERROR("check specific failed, ret is %d\n", spec_check_ret);
|
|
||||||
#if 0
|
|
||||||
toml_free(conf);
|
|
||||||
free(specific);
|
|
||||||
return -6;
|
|
||||||
#endif
|
|
||||||
specific_instance_destory(specific);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 插入到队列中 */
|
|
||||||
utarray_push_back(schema->lua_config_specific_array, specific);
|
|
||||||
specific_instance_destory(specific);
|
|
||||||
}
|
|
||||||
free(specific);
|
|
||||||
|
|
||||||
/* 返回加载的插件数量 */
|
|
||||||
return specific_num;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: lua_plugin_manage_state_load
|
|
||||||
* Input: | struct lua_plugin_manage_schema * | schema | 初始化的全局变量
|
|
||||||
* | int | thread_count | 初始化的线程数量
|
|
||||||
* Output:
|
|
||||||
* Return: | >= 0 | 创建完成, 并返回创建成功数量
|
|
||||||
* | -1 | 参数错误
|
|
||||||
* | -2 | 线程状态机初始化失败
|
|
||||||
* | -3 | 线程状态机加载过程失败
|
|
||||||
* Description: 依次创建好每个线程中的状态机
|
|
||||||
*/
|
|
||||||
int lua_plugin_manage_state_load(
|
|
||||||
struct lua_plugin_manage_schema *schema,
|
|
||||||
int thread_count)
|
|
||||||
{
|
|
||||||
if (__glibc_unlikely(!schema || thread_count <= 0 || thread_count >= LUA_PLUGIN_MANAGE_MAX_THREAD_COUNT))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
utarray_new(schema->lua_plugin_state_array, &thread_state_icd);
|
|
||||||
utarray_reserve(schema->lua_plugin_state_array, thread_count);
|
|
||||||
struct lua_thread_state new_thread_state;
|
|
||||||
for (int i = 1; i <= thread_count; ++i)
|
|
||||||
{
|
|
||||||
/* 依次初始化后加入链表 */
|
|
||||||
memset(&new_thread_state, 0, sizeof(new_thread_state));
|
|
||||||
if (thread_state_instance_init(&new_thread_state, i))
|
|
||||||
return -2;
|
|
||||||
utarray_push_back(schema->lua_plugin_state_array, &new_thread_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct lua_thread_state *thread_state = NULL;
|
|
||||||
while ((thread_state = utarray_next(schema->lua_plugin_state_array, thread_state)))
|
|
||||||
{
|
|
||||||
/* 依次对每一个线程中的状态机进行初始化 */
|
|
||||||
if (thread_state_instance_load(thread_state, schema))
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return thread_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -699,9 +241,12 @@ int lua_plugin_manage_state_load(
|
|||||||
*/
|
*/
|
||||||
struct lua_plugin_manage_schema *lua_plugin_manage_init(
|
struct lua_plugin_manage_schema *lua_plugin_manage_init(
|
||||||
struct stellar *st,
|
struct stellar *st,
|
||||||
const char *config_file_path)
|
int specific_count,
|
||||||
|
struct lua_config_specific *specific)
|
||||||
{
|
{
|
||||||
if (__glibc_unlikely(!st || !config_file_path))
|
if (__glibc_unlikely(!st))
|
||||||
|
return NULL;
|
||||||
|
if (__glibc_unlikely((specific_count && !specific) || (specific_count < 0)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct lua_plugin_manage_schema *new_schema = (struct lua_plugin_manage_schema *)calloc(1, sizeof(struct lua_plugin_manage_schema));
|
struct lua_plugin_manage_schema *new_schema = (struct lua_plugin_manage_schema *)calloc(1, sizeof(struct lua_plugin_manage_schema));
|
||||||
@@ -709,33 +254,67 @@ struct lua_plugin_manage_schema *lua_plugin_manage_init(
|
|||||||
return NULL;
|
return NULL;
|
||||||
memset(new_schema, 0, sizeof(struct lua_plugin_manage_schema));
|
memset(new_schema, 0, sizeof(struct lua_plugin_manage_schema));
|
||||||
|
|
||||||
new_schema->lua_plugin_schema_st = st;
|
new_schema->st = st;
|
||||||
/* 从配置文件中加载插件 */
|
|
||||||
new_schema->lua_config_specific_count = lua_plugin_manage_config_load(new_schema, config_file_path);
|
int thread_count = stellar_get_worker_thread_num(st);
|
||||||
LOGDEBUG("load config finish, load count is %d, file path is %s", new_schema->lua_config_specific_count, config_file_path);
|
new_schema->state_count = thread_count;
|
||||||
if (new_schema->lua_config_specific_count < 0)
|
/* 为后续待创建的lua_State预分配内存 */
|
||||||
|
new_schema->thread_state = (lua_State **)calloc(thread_count, sizeof(lua_State *));
|
||||||
|
if (__glibc_unlikely(!new_schema->thread_state))
|
||||||
{
|
{
|
||||||
/* 可以没有插件配置, 但是不能在加载过程中出错 */
|
|
||||||
lua_plugin_manage_exit(new_schema);
|
lua_plugin_manage_exit(new_schema);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
memset(new_schema->thread_state, 0, thread_count * sizeof(lua_State *));
|
||||||
struct lua_config_specific *specific = NULL;
|
/* 为将要加载的模块预分配内存 */
|
||||||
int unittest_config_num = 0;
|
new_schema->model_count = specific_count;
|
||||||
while ((specific = utarray_next(new_schema->lua_config_specific_array, specific)))
|
new_schema->model = (struct lua_model *)calloc(specific_count, sizeof(struct lua_model));
|
||||||
|
if (__glibc_unlikely(!new_schema->model))
|
||||||
{
|
{
|
||||||
printf("path[%d] is %s\n", unittest_config_num, specific->config_specific_file);
|
lua_plugin_manage_exit(new_schema);
|
||||||
printf("load[%d] is %s\n", unittest_config_num, specific->config_specific_load_func);
|
return NULL;
|
||||||
printf("unload[%d] is %s\n", unittest_config_num, specific->config_specific_unload_func);
|
|
||||||
unittest_config_num += 1;
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
memset(new_schema->model, 0, specific_count * sizeof(struct lua_model));
|
||||||
#endif
|
|
||||||
|
|
||||||
int thread_count = stellar_get_worker_thread_num(st);
|
/* 依次初始化每个状态机 */
|
||||||
/* 依次创建线程状态机, 并加入链表 */
|
for (int thread_index = 0; thread_index < thread_count; ++thread_index)
|
||||||
new_schema->lua_plugin_state_count = lua_plugin_manage_state_load(new_schema, thread_count);
|
{
|
||||||
LOGDEBUG("load thread state finish, load count is %d", new_schema->lua_plugin_state_count);
|
/* 创建状态机 */
|
||||||
|
new_schema->thread_state[thread_index] = thread_state_init(thread_index);
|
||||||
|
if (__glibc_unlikely(!new_schema->thread_state[thread_index]))
|
||||||
|
{
|
||||||
|
lua_plugin_manage_exit(new_schema);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int spec_index = 0; spec_index < specific_count; ++spec_index)
|
||||||
|
{
|
||||||
|
/* 在状态机中加载specific中的配置 */
|
||||||
|
int load_ret = thread_state_load_specific(new_schema->thread_state[thread_index],
|
||||||
|
&new_schema->model[spec_index],
|
||||||
|
&specific[spec_index]);
|
||||||
|
if (load_ret)
|
||||||
|
{
|
||||||
|
LOGERROR("state load specific failed, ret is %d", load_ret);
|
||||||
|
lua_plugin_manage_exit(new_schema);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 调用该模块中的load函数 */
|
||||||
|
int call_load_ret = thread_state_call_load(new_schema->thread_state[thread_index],
|
||||||
|
&new_schema->model[spec_index],
|
||||||
|
&specific[spec_index],
|
||||||
|
st);
|
||||||
|
if (call_load_ret)
|
||||||
|
{
|
||||||
|
LOGERROR("call state load function failed, ret is %d", call_load_ret);
|
||||||
|
lua_plugin_manage_exit(new_schema);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug_lua_plugin_manage_schema(new_schema);
|
||||||
|
global_schema = new_schema;
|
||||||
|
|
||||||
return new_schema;
|
return new_schema;
|
||||||
}
|
}
|
||||||
@@ -751,10 +330,31 @@ void lua_plugin_manage_exit(struct lua_plugin_manage_schema *lua_plug_mgr)
|
|||||||
{
|
{
|
||||||
if (__glibc_unlikely(!lua_plug_mgr))
|
if (__glibc_unlikely(!lua_plug_mgr))
|
||||||
return;
|
return;
|
||||||
if (lua_plug_mgr->lua_config_specific_array)
|
|
||||||
utarray_free(lua_plug_mgr->lua_config_specific_array);
|
/* 释放所有的状态机 */
|
||||||
if (lua_plug_mgr->lua_plugin_state_array)
|
for (int state_index = 0; state_index < lua_plug_mgr->state_count; ++state_index)
|
||||||
utarray_free(lua_plug_mgr->lua_plugin_state_array);
|
{
|
||||||
|
for (int model_index = 0; model_index < lua_plug_mgr->model_count; ++model_index)
|
||||||
|
{
|
||||||
|
/* 在状态机中对每一个模块调用对应的卸载函数 */
|
||||||
|
int call_unload_ret = thread_state_call_unload(lua_plug_mgr->thread_state[state_index],
|
||||||
|
&lua_plug_mgr->model[model_index]);
|
||||||
|
if ( call_unload_ret ) {
|
||||||
|
LOGERROR("call state unload function failed, ret is %d", call_unload_ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 销毁状态机 */
|
||||||
|
lua_close(lua_plug_mgr->thread_state[state_index]);
|
||||||
|
}
|
||||||
|
free(lua_plug_mgr->thread_state);
|
||||||
|
|
||||||
|
/* 释放所有加载的模块 */
|
||||||
|
for (int model_index = 0; model_index < lua_plug_mgr->model_count; ++model_index)
|
||||||
|
{
|
||||||
|
utarray_free(lua_plug_mgr->model[model_index].plugin_array);
|
||||||
|
}
|
||||||
|
free(lua_plug_mgr->model);
|
||||||
|
|
||||||
free(lua_plug_mgr);
|
free(lua_plug_mgr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -797,4 +397,27 @@ void debug_lua_state_stack(lua_State * state, int mod, const char * message)
|
|||||||
}
|
}
|
||||||
printf("***** end of debug one lua stack *****\n\n");
|
printf("***** end of debug one lua stack *****\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void debug_lua_plugin_manage_schema(struct lua_plugin_manage_schema * schema)
|
||||||
|
{
|
||||||
|
printf("\n***** begin to debug one lua schema *****\n");
|
||||||
|
printf("schema.st is %p\n", schema->st);
|
||||||
|
printf("schema state count is %d\n", schema->state_count);
|
||||||
|
for ( int i = 0; i < schema->state_count; ++i ) {
|
||||||
|
printf("schema state[%d]pointer is %p\n", i, schema->thread_state[i]);
|
||||||
|
}
|
||||||
|
printf("schema model count is %d\n", schema->model_count);
|
||||||
|
for ( int i = 0; i < schema->model_count; ++i ) {
|
||||||
|
printf("debug model[%d]\n", i);
|
||||||
|
printf("array %p, load %d, unload %d, env %d, mark %04x, count %04x\n",
|
||||||
|
schema->model[i].plugin_array, schema->model[i].load_ref, schema->model[i].unload_ref,
|
||||||
|
schema->model[i].private_env_ref, schema->model[i].model_mark, schema->model[i].plugin_count);
|
||||||
|
struct lua_plugin * plugin = NULL;
|
||||||
|
while ((plugin = utarray_next(schema->model[i].plugin_array, plugin))) {
|
||||||
|
printf("%d, %d, %d\n", plugin->plugin_id, plugin->ctx_new_ref, plugin->ctx_free_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("***** end of debug one lua schema *****\n\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -69,6 +69,11 @@
|
|||||||
* BugFix:
|
* BugFix:
|
||||||
* 修改struct lua_plugin_env, 其中增加文件路径
|
* 修改struct lua_plugin_env, 其中增加文件路径
|
||||||
* 防止在加载过程中由于函数重名导致的加载错误
|
* 防止在加载过程中由于函数重名导致的加载错误
|
||||||
|
*
|
||||||
|
* 08-08
|
||||||
|
* 整体重构状态机相关结构定义, 拆分高频访问数据与低频访问数据
|
||||||
|
* 状态机中数据管理由树形结构修改为数组型结构
|
||||||
|
* 经过多次验证, 相同状态机在执行相同操作后返回结果及中间产物一致, 合并一些冗余数据
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#ifndef LUA_PLUGIN_MANAGE_INTERNAL_H
|
#ifndef LUA_PLUGIN_MANAGE_INTERNAL_H
|
||||||
#define LUA_PLUGIN_MANAGE_INTERNAL_H
|
#define LUA_PLUGIN_MANAGE_INTERNAL_H
|
||||||
@@ -81,7 +86,31 @@
|
|||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
|
|
||||||
#include <time.h>
|
enum LUA_PLUGIN_RETURN
|
||||||
|
{
|
||||||
|
/* 状态机相关的错误码 */
|
||||||
|
STATE_LOAD_FILE_ERR = -400, /* 状态机加载lua文件时出错, 可能原因是文件不存在或文件无法加载 */
|
||||||
|
STATE_CREATE_ENV_FAIL, /* 在状态机中创建新的plugin_env时出现错误, 无法创建或该模块之前加载过程中的引用ID与新创建ID不同 */
|
||||||
|
STATE_GET_LOAD_FAIL, /* 状态机加载load函数时出现错误, 该函数不存在或引用ID有问题 */
|
||||||
|
STATE_GET_UNLOAD_FAIL, /* 状态机加载unload函数时出现错误, 该函数不存在或引用ID有问题 */
|
||||||
|
/* lua代码块运行错误码 */
|
||||||
|
CHUNK_TYPE_NOT_FUNCTION = -300, /* 获取得到的代码块类型并非可执行的lua语句, 无法执行 */
|
||||||
|
CHUNK_RUN_CODE_FAIL, /* 调用代码过程中运行失败, 失败的具体报错信息会保存在栈中, 通过日志输出 */
|
||||||
|
CHUNK_RCOUNT_ERR, /* 尝试接收返回值, 但传入接收返回值的队列长度小于实际返回值个数 */
|
||||||
|
/* lua与C之间数据转换或操作错误码 */
|
||||||
|
DATA_PUSHSTACK_ERR = -200, /* 数据入栈过程中遇到未知的问题 */
|
||||||
|
DATA_POPSTACK_ERR, /* 数据从状态机中出栈过程中遇到未知的问题 */
|
||||||
|
DATA_POPSTACK_NODATA, /* 出栈过程中栈内无数据, 导致出栈失败 */
|
||||||
|
DATA_TYPE_UNKNOWN, /* 无法识别的struct lua_cdata数据类型, 或在该函数中操作了不支持的数据类型 */
|
||||||
|
/* 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, /* 运行成功 */
|
||||||
|
};
|
||||||
|
|
||||||
/* ***** ***** ***** ***** ***** ***** */
|
/* ***** ***** ***** ***** ***** ***** */
|
||||||
/* 此部分主要功能为C向lua中注册函数及数据, 实现在lua_plugin_binding.c中 */
|
/* 此部分主要功能为C向lua中注册函数及数据, 实现在lua_plugin_binding.c中 */
|
||||||
@@ -89,11 +118,11 @@
|
|||||||
struct lua_binding_function
|
struct lua_binding_function
|
||||||
{
|
{
|
||||||
/* 注册函数原型 */
|
/* 注册函数原型 */
|
||||||
lua_CFunction binding_function;
|
lua_CFunction function;
|
||||||
/* 注册至lua中的函数名称 */
|
/* 注册至lua中的函数名称 */
|
||||||
char *binding_function_name;
|
char *function_name;
|
||||||
/* 注册至lua中的命名空间名称 */
|
/* 注册至lua中的命名空间名称 */
|
||||||
char *binding_function_space_name;
|
char *space_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 定义在lua_plugin_binding.c文件中 */
|
/* 定义在lua_plugin_binding.c文件中 */
|
||||||
@@ -120,6 +149,7 @@ enum DATATYPE
|
|||||||
DATATYPE_TABLE,
|
DATATYPE_TABLE,
|
||||||
/* 指针类型 */
|
/* 指针类型 */
|
||||||
DATATYPE_POINTER,
|
DATATYPE_POINTER,
|
||||||
|
/* context上下文类型 */
|
||||||
DATATYPE_CONTEXT,
|
DATATYPE_CONTEXT,
|
||||||
DATATYPE_END
|
DATATYPE_END
|
||||||
};
|
};
|
||||||
@@ -128,13 +158,13 @@ enum DATATYPE
|
|||||||
struct lua_binding_data
|
struct lua_binding_data
|
||||||
{
|
{
|
||||||
/* 注册的数据类型 */
|
/* 注册的数据类型 */
|
||||||
enum DATATYPE binding_data_type;
|
enum DATATYPE data_type;
|
||||||
/* 注册数数据值 */
|
/* 注册数数据值 */
|
||||||
char *binding_data_value;
|
char *data_value;
|
||||||
/* 注册的数据名称 */
|
/* 注册的数据名称 */
|
||||||
char *binding_data_name;
|
char *data_name;
|
||||||
/* 注册至lua中的命名空间名称 */
|
/* 注册至lua中的命名空间名称 */
|
||||||
char *binding_data_space_name;
|
char *space_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 定义在lua_plugin_binding.c中 */
|
/* 定义在lua_plugin_binding.c中 */
|
||||||
@@ -186,9 +216,9 @@ struct lua_context
|
|||||||
/* 在状态机中生成一个context */
|
/* 在状态机中生成一个context */
|
||||||
struct lua_context *lua_context_new(lua_State *state);
|
struct lua_context *lua_context_new(lua_State *state);
|
||||||
/* 将一个context入栈 */
|
/* 将一个context入栈 */
|
||||||
int lua_context_push_stack(struct lua_context *context);
|
int lua_context_push_stack(lua_State *state, struct lua_context *context);
|
||||||
/* 释放一个context */
|
/* 释放一个context */
|
||||||
void lua_context_free(struct lua_context *context);
|
void lua_context_free(lua_State *state, struct lua_context *context);
|
||||||
|
|
||||||
/* ***** ***** ***** ***** ***** ***** */
|
/* ***** ***** ***** ***** ***** ***** */
|
||||||
/* 此部分为注册至C中的lua通用函数, 实现在lua_plugin_cfunc.c中 */
|
/* 此部分为注册至C中的lua通用函数, 实现在lua_plugin_cfunc.c中 */
|
||||||
@@ -197,141 +227,79 @@ 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);
|
// void lpm_on_session_msg_func(struct session *sess, int topic_id, const void *msg, void *sess_ctx, void *plugin_env);
|
||||||
|
|
||||||
/* ***** ***** ***** ***** ***** ***** */
|
/* ***** ***** ***** ***** ***** ***** */
|
||||||
/* 此部分主要为插件管理及配置管理相关功能, 实现在lua_plugin_manage.c中 */
|
/* lua代码块相关操作, 实现在lua_plugin_chunk.c中 */
|
||||||
struct lua_config_specific;
|
/* 执行一段lua代码块, 执行之前需要先在lua中生成一个引用ID */
|
||||||
struct lua_script;
|
int lua_chunk_execute(lua_State *state, int ref_id, int pcount, struct lua_cdata *params, int rcount, struct lua_cdata *returns);
|
||||||
struct lua_session_plugin;
|
|
||||||
struct lua_plugin_env;
|
|
||||||
struct lua_thread_state;
|
|
||||||
struct lua_plugin_manage_schema;
|
|
||||||
|
|
||||||
/* 根据配置文件加载过程中保存插件信息的临时结构 */
|
/* ***** ***** ***** ***** ***** ***** */
|
||||||
struct lua_config_specific
|
/* 状态机相关的一些数据结构及操作, 实现在lua_plugin_manage.c中 */
|
||||||
|
|
||||||
|
extern struct lua_plugin_manage_schema *global_schema;
|
||||||
|
|
||||||
|
/* TODO:统计插件的运行情况, 暂时没想好怎么用 */
|
||||||
|
/* 记录一个插件的运行状态 */
|
||||||
|
struct lua_plugin_statistics
|
||||||
{
|
{
|
||||||
/* 插件需要使用的文件名 */
|
/* ctx_new函数调用成功的次数 */
|
||||||
char *config_specific_file;
|
int new_success_count;
|
||||||
/* 插件名称 */
|
/* ctx_new函数调用失败的次数 */
|
||||||
// char *config_specific_name;
|
int new_failed_count;
|
||||||
/* 加载插件需要调用的函数名称 */
|
/* ctx_free函数调用成功的次数 */
|
||||||
char *config_specific_load_func;
|
int free_success_count;
|
||||||
/* 卸载插件需要调用的函数名称 */
|
/* ctx_free函数调用失败的次数 */
|
||||||
char *config_specific_unload_func;
|
int free_failed_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
void specific_instance_copy(void *dst, const void *src);
|
/* 保存Lua插件信息 */
|
||||||
void specific_instance_destory(void *elt);
|
struct lua_plugin
|
||||||
|
|
||||||
/* 一个可以运行的lua函数 */
|
|
||||||
/* 加载过程中生成引用, 后续使用过程中使用引用编号进行调用 */
|
|
||||||
struct lua_script
|
|
||||||
{
|
{
|
||||||
/* 该函数注册时注册至的状态机, 运行过程中使用该状态机调用函数 */
|
/* 注册完成后得到的插件ID */
|
||||||
lua_State *script_state;
|
|
||||||
/* 该函数的引用ID */
|
|
||||||
int script_ref_id;
|
|
||||||
|
|
||||||
/* 运行成功次数 */
|
|
||||||
int script_run_success;
|
|
||||||
/* 运行失败次数 */
|
|
||||||
int script_run_failed;
|
|
||||||
/* 最后一次运行开始时间 */
|
|
||||||
clock_t script_last_ms_start;
|
|
||||||
/* 最后一次运行结束时间 */
|
|
||||||
clock_t script_last_ms_end;
|
|
||||||
/* 运行总用时 */
|
|
||||||
clock_t script_total_ms;
|
|
||||||
};
|
|
||||||
|
|
||||||
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 pcount, struct lua_cdata *param, int rmaxcount, struct lua_cdata *rvalue);
|
|
||||||
|
|
||||||
/* 每一个插件的函数信息 */
|
|
||||||
struct lua_session_plugin
|
|
||||||
{
|
|
||||||
/* 插件注册完成后得到的插件编号 */
|
|
||||||
int plugin_id;
|
int plugin_id;
|
||||||
|
/* context_new函数在状态机中的引用值 */
|
||||||
/* ctx_new函数 */
|
int ctx_new_ref;
|
||||||
struct lua_script plugin_ctx_new_script;
|
/* context_free函数在状态机中的引用值 */
|
||||||
/* ctx_free函数 */
|
int ctx_free_ref;
|
||||||
struct lua_script plugin_ctx_free_script;
|
|
||||||
/* on_message函数 */
|
|
||||||
// struct lua_script plugin_on_message_script;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int session_plugin_instance_init(struct lua_session_plugin *session_plugin, lua_State *state, int plugin_id, int new_refid, int free_refid);
|
#define MODEL_MARK_INIT_DONE 0x0001
|
||||||
void session_plugin_instance_destory(void *elt);
|
#define MODEL_MARK_LOAD_DONE 0x0002
|
||||||
|
|
||||||
#define PLUGIN_ENV_DEFAULT_KEY "penv_pointer"
|
/* 加载的lua模块, 一个lua模块一般来说对应一个lua文件, 与C插件管理中的so相同 */
|
||||||
|
struct lua_model
|
||||||
/* 调用插件加载函数时得到的运行环境数据 */
|
|
||||||
struct lua_plugin_env
|
|
||||||
{
|
{
|
||||||
/* 插件注册的状态机 */
|
/* 该模块注册后的插件列表 */
|
||||||
lua_State *plugin_env_state;
|
UT_array *plugin_array;
|
||||||
/* 该环境数据中包含的所有插件列表 */
|
/* 该模块load函数在状态机中的引用值 */
|
||||||
UT_array *plugin_env_plugin_array;
|
int load_ref;
|
||||||
|
/* 该模块unload函数在状态机中的引用值 */
|
||||||
/* 加载插件的lua函数 */
|
int unload_ref;
|
||||||
struct lua_script plugin_env_load_func;
|
/* 该模块创建出的plugin_env数据在状态机中的引用值 */
|
||||||
/* 卸载插件的lua函数 */
|
int private_env_ref;
|
||||||
struct lua_script plugin_env_unload_func;
|
/* 初始化过程中的标记 */
|
||||||
|
unsigned short model_mark;
|
||||||
/* 该插件运行环境数据的名称, 在创建时同时在状态机中创建该名称的命名空间 */
|
/* 加载的插件数量 */
|
||||||
/* 插件申请lua内的全局变量可以保存在该命名空间内, 防止被其他内容覆盖 */
|
unsigned short plugin_count;
|
||||||
// char *plugin_env_name;
|
|
||||||
|
|
||||||
/* bugfix */
|
|
||||||
/* 增加文件路径, 防止在加载过程中出现重名的情况导致加载错误 */
|
|
||||||
char * plugin_env_filepath;
|
|
||||||
|
|
||||||
/* 在lua中保存运行数据的引用ID */
|
|
||||||
int plugin_env_ref_id; /* plugin_env */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 此时不创建session_array, 在调用load函数过程中创建 */
|
|
||||||
int plugin_env_instance_init(struct lua_plugin_env *plugin_env, lua_State *state, struct lua_config_specific *specific);
|
|
||||||
void plugin_env_instance_destory(void *elt);
|
|
||||||
|
|
||||||
/* 每一个线程中保存一个状态机数据 */
|
|
||||||
struct lua_thread_state
|
|
||||||
{
|
|
||||||
/* 创建状态机的线程ID */
|
|
||||||
int thread_id;
|
|
||||||
/* 已经插入的插件数量 */
|
|
||||||
int thread_plugin_count;
|
|
||||||
/* 生成的状态机 */
|
|
||||||
lua_State *thread_state;
|
|
||||||
// struct lua_pl_state_private * lua_thread_private;
|
|
||||||
/* 该线程状态机中注册的插件列表 */
|
|
||||||
UT_array *thread_env_array;
|
|
||||||
/* 状态机的启动时间 */
|
|
||||||
time_t thread_begin_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
int thread_state_instance_init(struct lua_thread_state *thread_state, int state_id);
|
|
||||||
void thread_state_instance_destory(void *elt);
|
|
||||||
int thread_state_instance_load(struct lua_thread_state *thread_state, struct lua_plugin_manage_schema *schema);
|
|
||||||
|
|
||||||
struct lua_plugin_manage_schema
|
struct lua_plugin_manage_schema
|
||||||
{
|
{
|
||||||
struct stellar *lua_plugin_schema_st;
|
struct stellar *st;
|
||||||
int lua_config_specific_count;
|
|
||||||
UT_array *lua_config_specific_array;
|
/* 创建的状态机数量, 状态机数量与线程的个数相同 */
|
||||||
int lua_plugin_state_count;
|
int state_count;
|
||||||
UT_array *lua_plugin_state_array;
|
lua_State **thread_state;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
int model_count;
|
||||||
|
struct lua_model *model;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 防止参数错误, 暂时定一个上限 */
|
#define LUA_PLUGIN_ENV_DEFAULT_KEY "__penv_pointer"
|
||||||
#define LUA_PLUGIN_MANAGE_MAX_THREAD_COUNT 10
|
#define LUA_STATE_THREAD_ID_KEY "__thread_id"
|
||||||
|
|
||||||
int lua_plugin_manage_config_load(struct lua_plugin_manage_schema *schema, const char *config_file_name);
|
|
||||||
int lua_plugin_manage_state_load(struct lua_plugin_manage_schema *schema, int thread_count);
|
|
||||||
|
|
||||||
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
#ifdef LUAPLUGIN_BASIC_UNITTEST
|
||||||
void debug_lua_state_stack(lua_State *state, int mod, const char *message);
|
void debug_lua_state_stack(lua_State *state, int mod, const char *message);
|
||||||
|
void debug_lua_plugin_manage_schema(struct lua_plugin_manage_schema *schema);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user