// skynet模块
struct skynet_module {
const char * name; // 模块名字
void * module; // 模块的句柄,通过dlopen函数获得
skynet_dl_create create; // 创建函数
skynet_dl_init init; // 初始化函数
skynet_dl_release release; // 释放函数
skynet_dl_signal signal; // 处理信号函数
};一个模块本质就是一个动态链接库文件,它必须要实现以下接口(xxx为动态链接库文件名):
typedef void * (*skynet_dl_create)(void)
typedef int (*skynet_dl_init)(void * inst, struct skynet_context *, const char * parm)
inst当前module实例skynet_context上下文parm参数
初始化模块,指定消息的回调函数;
typedef void (*skynet_dl_release)(void * inst)
释放模块
TODO
skynet限制了最大模块数量:
#define MAX_MODULE_TYPE 32 // 最大模块数量skynet 通过modules来管理模块,其定义如下:
// 模块集合
struct modules {
int count; // 模块类型id
struct spinlock lock; // 自旋锁
const char * path; // 模块集合的共有路径
struct skynet_module m[MAX_MODULE_TYPE]; // 模块集合
};
static struct modules * M = NULL; // 模块集合单例void *dlopen(const char *filename, int flags)类unix系统提供了函数dlopen来加载动态链接库文件,它会按照相应的逻辑来搜索文件。
void *dlsym(void *handle, const char *symbol)类unix系统提供了函数dlsym来解析动态链接库符号,返回符号对应的地址。
int dlclose(void *handle)类unix系统提供了函数dlclose来关闭指定句柄的动态链接库;注意:只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
skynet在创建完module实例并初始化后,同时创建了一个skynet_context,并将module实例和skynet_context关联起来,最后放置于handle_storage的slot里面,这样一个个独立的沙盒环境就这样被创建出来了。
详情请看:skynet服务
typedef int (*skynet_cb)(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz)context上下文ud一般是instance指针type消息类型session凭证source发送方的服务idmsg数据sz数据大小
当消息到达skynet_context时,会调用skynet_cb
TODO