skynet是如何实现c和lua的控制权转换
前面已经讲过c底层代码是如果完成消息驱动的,这里主要描述c和lua是如何进行交互和转移控制权的。
lua服务的起源地
skynet所有的lua服务都是有service_snlua.c的实现的库是加载的。
/*skynet_context_new中加载snlua的库时会调用init*/
int snlua_init(struct snlua *l, struct skynet_context *ctx, const char * args) {
int sz = strlen(args);
char * tmp = skynet_malloc(sz);
memcpy(tmp, args, sz);
/*设置回调*/
skynet_callback(ctx, l , launch_cb);
/*注册服务名字,NULL表示使用handle id做为服务名称*/
const char * self = skynet_command(ctx, "REG", NULL);
uint32_t handle_id = strtoul(self+1, NULL, 16);
// it must be first message
skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY,0, tmp, sz);
return 0;
}
skynet_context_new创建snlua后,消息队列直接加入了全局队列,消息驱动会触发回调launch_cb
static int launch_cb(struct skynet_context * context, void *ud, int type, int session, uint32_t source , const void * msg, size_t sz) {
assert(type == 0 && session == 0);
struct snlua *l = ud;
/*这里直接注销的回调,为后续lua通过注册的方式接过业务的控制权做准备*/
skynet_callback(context, NULL, NULL);
/*这里主要是加载运行lua服务*/
int err = init_cb(l, context, msg, sz);
if (err) {
skynet_command(context, "EXIT", NULL);
}
return 0;
}
以bootstrap服务为例,lua加载运行skynet.start
local c = require