搞清楚了,感谢静龙画的图。LUA和c的互操作真抽象,还有很多函数搞不懂啥意思。
On Jun 20, 3:43 pm, pengqi <fengm...@gmail.com> wrote:
> 所有的协程应该是保存在一个table中,这个table保存在registry里面,
> lua_getfield(L, LUA_REGISTRYINDEX, NGX_LUA_CORT_REF);
> 这一句从registry表得到这个table并保存一份在栈上,
> L的栈:
> --------------------
> | cort_table |
> --------------------
> 接着 cr = lua_newthread(L); 新建一个协程并压入L的栈,
> L的栈:
> --------------------
> | cr |
> --------------------
> | cort_table |
> --------------------
> 如果分配协程成功,继续初始化,首先分配新全局表,并压入cr的栈:
> /* new globals table for coroutine */
> lua_newtable(cr);
> cr的栈:
> -------------------
> | _G (new) |
> -------------------
> 为新全局表分配新的metatable :
> lua_createtable(cr, 0, 1);
> cr的栈:
> -------------------
> | metatable |
> -------------------
> | _G (new) |
> -------------------
> 设置metatable的__index为旧的全局表(继承之),先得到旧的全局表,并压入cr的栈:
> lua_pushvalue(cr, LUA_GLOBALSINDEX);
> cr的栈:
> -------------------
> | _G (old) |
> -------------------
> | metatable |
> -------------------
> | _G (new) |
> -------------------
> 设置metatable的__index为旧的全局表:
> lua_setfield(cr, -2, "__index");
> lua_setmetatable(cr, -2);
> cr的栈:
> -------------------
> | _G (new) |
> -------------------
> 将新建的协程全局表替换为新的:
> lua_replace(cr, LUA_GLOBALSINDEX);
> cr的栈:
> 空(不包括新建的时候压入的)
>
> 将新建的协程保存在协程表当中,并得到相应的索引:
> *ref = luaL_ref(L, -2);
> L的栈:
> --------------------
> | cort_table |
> --------------------
> 清空L的栈:
> lua_pop(L, 1);
> L栈:
> 空
>
> 2012/6/20 Simon <bigp...@gmail.com>
>
>
>
>
>
>
>
>
>
> > 下面代码提到 /* pop coroutine reference on main thread's stack after
> > anchoring it
> > * in registry */
>
> > 但是并没看到有将cr放到registry的地方,是lua_getfield(L, LUA_REGISTRYINDEX,
> > NGX_LUA_CORT_REF);这个语句吗?可是这时候cr还未生成呢。
>
> > lua_State *
> > ngx_http_lua_new_thread(ngx_http_request_t *r, lua_State *L, int *ref)
> > {
> > int top;
> > lua_State *cr;
>
> > ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
> > "lua creating new thread");
>
> > top = lua_gettop(L);
>
> > lua_getfield(L, LUA_REGISTRYINDEX, NGX_LUA_CORT_REF);
>
> > cr = lua_newthread(L);
>
> > if (cr) {
> > /* new globals table for coroutine */
> > lua_newtable(cr);
>
> > /* {{{ inherit coroutine's globals to main thread's globals
> > table
> > * for print() function will try to find tostring() in
> > current
> > * globals * table. */
> > lua_createtable(cr, 0, 1);
> > lua_pushvalue(cr, LUA_GLOBALSINDEX);
> > lua_setfield(cr, -2, "__index");
> > lua_setmetatable(cr, -2);
> > /* }}} */
>
> > lua_replace(cr, LUA_GLOBALSINDEX);
>
> > *ref = luaL_ref(L, -2);
>
> > if (*ref == LUA_NOREF) {
> > lua_settop(L, top); /* restore main thread stack */
> > return NULL;
> > }
> > }
>
> > /* pop coroutine reference on main thread's stack after anchoring
> > it
> > * in registry */
> > lua_pop(L, 1);
>
> > return cr;
> > }
>
> > --
> Jinglong
> Software Engineer
> Server Platforms Team at Taobao