S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

_init() 函数分析 (一) 2014.11.04

Posted on 2014-11-04 21:23 S.l.e!ep.¢% 阅读(655) 评论(0)  编辑 收藏 引用 所属分类: Skynet
 1 static int
 2 _init(struct snlua *l, struct skynet_context *ctx, const char * args, size_t sz) {
 3     lua_State *= l->L;
 4     l->ctx = ctx;
 5     lua_gc(L, LUA_GCSTOP, 0); 
 6     lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
 7     lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
 8     luaL_openlibs(L);
 9     lua_pushlightuserdata(L, ctx);
10     lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");
11     luaL_requiref(L, "skynet.codecache", codecache , 0);
12     lua_pop(L,1);
13 
14     const char *path = optstring(ctx, "lua_path","./lualib/?.lua;./lualib/?/init.lua");
15     lua_pushstring(L, path);
16     lua_setglobal(L, "LUA_PATH");
17     const char *cpath = optstring(ctx, "lua_cpath","./luaclib/?.so");
18     lua_pushstring(L, cpath);
19     lua_setglobal(L, "LUA_CPATH");
20     const char *service = optstring(ctx, "luaservice""./service/?.lua");
21     lua_pushstring(L, service);
22     lua_setglobal(L, "LUA_SERVICE");
23     const char *preload = skynet_command(ctx, "GETENV""preload");
24     lua_pushstring(L, preload);
25     lua_setglobal(L, "LUA_PRELOAD");
26 
27     lua_pushcfunction(L, traceback);
28     assert(lua_gettop(L) == 1);
29 
30     const char * loader = optstring(ctx, "lualoader""./lualib/loader.lua");
31 
32     int r = luaL_loadfile(L,loader);
33     if (r != LUA_OK) {
34         skynet_error(ctx, "Can't load %s : %s", loader, lua_tostring(L, -1));
35         _report_launcher_error(ctx);
36         return 1;
37     }
38     lua_pushlstring(L, args, sz);
39     r = lua_pcall(L,1,0,1);
40     if (r != LUA_OK) {
41         skynet_error(ctx, "lua loader error : %s", lua_tostring(L, -1));
42         _report_launcher_error(ctx);
43         return 1;
44     }
45     lua_settop(L,0);
46 
47     lua_gc(L, LUA_GCRESTART, 0); 
48 
49     return 0;
50 }
    
函数的开始和最后,分别调了
lua_gc(L, LUA_GCSTOP, 0); //停止GC 和  lua_gc(L, LUA_GCRESTART, 0); //重启GC
是为了保证在整个 service 执行逻辑期间中途不会被 gc?


lua_pushboolean(L, 1);  /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");

lua_pushlightuserdata(L, ctx);
lua_setfield(L, LUA_REGISTRYINDEX, "skynet_context");

这四句可以参考 这篇BLOG的上半部份, 就是把一些数据放到 lua 的状态机(
lua_State)中
"LUA_NOENV" 和 "skynet_context" 分别是 key
LUA_NOENV  ===> 1
skynet_context ===> ctx

在其它地方获取的代码
lua_getfield(L, LUA_REGISTRYINDEX, "skynet_context");
    struct skynet_context *ctx = lua_touserdata(L,-1);
    if (ctx == NULL) {
        return luaL_error(L, "Init skynet context first");
    }
在 \lualib-src\lua-skynet.c 和 \lualib-src\lua-socket.c 可以找到

至于"LUA_NOENV"是否是lua的内部变量,这里告诉lua不使用环境变量?

luaL_openlibs(L);    //载入所有lua标准库



luaL_requiref(L, "skynet.codecache", codecache , 0);
lua_pop(L,1);

在lua中调用C的函数,lua提供了一种方法,是这样的, 但是呢, 也可以这样来用

lua_pop(L,1); 这句未知意图,难道是调用 luaL_requiref() 后需要 pop ?



14     const char *path = optstring(ctx, "lua_path","./lualib/?.lua;./lualib/?/init.lua");
15     lua_pushstring(L, path);
16     lua_setglobal(L, "LUA_PATH");
17     const char *cpath = optstring(ctx, "lua_cpath","./luaclib/?.so");
18     lua_pushstring(L, cpath);
19     lua_setglobal(L, "LUA_CPATH");
20     const char *service = optstring(ctx, "luaservice""./service/?.lua");
21     lua_pushstring(L, service);
22     lua_setglobal(L, "LUA_SERVICE");
23     const char *preload = skynet_command(ctx, "GETENV""preload");
24     lua_pushstring(L, preload);
25     lua_setglobal(L, "LUA_PRELOAD");

void lua_setglobal (lua_State *L, const char *name);

Pops a value from the stack and sets it as the new value of global name.

大概意思,从堆栈弹出一个值,设置到全局的 name 里去

LUA_API void lua_setglobal (lua_State *L, const char *var) {
  Table 
*reg = hvalue(&G(L)->l_registry);
  
const TValue *gt;  /* global table */
  lua_lock(L);
  api_checknelems(L, 
1);
  gt 
= luaH_getint(reg, LUA_RIDX_GLOBALS);
  setsvalue2s(L, L
->top++, luaS_new(L, var));
  luaV_settable(L, gt, L
->top - 1, L->top - 2);
  L
->top -= 2;  /* pop value and key */
  lua_unlock(L);
}

LUA_API 
void lua_setfield (lua_State *L, int idx, const char *k) {
  StkId t;
  lua_lock(L);
  api_checknelems(L, 
1);
  t 
= index2addr(L, idx);
  setsvalue2s(L, L
->top++, luaS_new(L, k));
  luaV_settable(L, t, L
->top - 1, L->top - 2);
  L
->top -= 2;  /* pop value and key */
  lua_unlock(L);
}

lua_setfield
[
-1+0, e]
void lua_setfield (lua_State *L, int index, const char *k);
Does the equivalent to t[k] 
= v, where t is the value at the given index and v is the value at the top of the stack.
This function pops the value from the stack. As 
in Lua, this function may trigger a metamethod for the "newindex" event (see §2.4)

lua_setglobal
[
-1+0, e]
void lua_setglobal (lua_State *L, const char *name);
Pops a value from the stack and sets it 
as the new value of global name. 


lua_setfield 和 lua_setglobal 从源码上看,  lua_setglobal实际上也是调用 lua_setfield 放到一个 LUA_RIDX_GLOBALS 的表里而已


27     lua_pushcfunction(L, traceback);
28     assert(lua_gettop(L) == 1);

这两句将一个C函数push到堆栈?然后 lua_gettop() 判断下? 这里为何没有 pop? 用意暂时不清楚

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理