Hello!
2014-02-20 19:17 GMT-08:00 ocher:
> 比如:一个请求进来后ngx_lua在哪里新建了coroutine,
这取决于你具体使用的是哪一个 hook. 对于 content_by_lua 而言,调用轨迹是
ngx_http_lua_content_handler -> ngx_http_lua_content_handler_inline ->
ngx_http_lua_content_by_chunk -> ngx_http_lua_new_thread ->
ngx_http_lua_run_thread.
细节见 src/ngx_http_lua_contentby.c 和 src/ngx_http_lua_util.c.
> 在脚本中使用cosocket的时候如何把控制权转移给nginx,然后又是怎么(和当发生什么时)再次得到控制权,ngx_lua如何调度各个协程的?
cosocket API 在当前 IO 操作不能立即完成时会调用 lua_yield 把控制权交还给 nginx:
http://www.lua.org/manual/5.1/manual.html#lua_yield
具体的代码可以参见 src/ngx_http_lua_socket_tcp.c.
然后当有新的 IO 事件并且尚未完成的 IO 操作可以完成时,再通过 ctx->resume_handler (对于 tcp
cosocket 就是 ngx_http_lua_socket_tcp_resume)切回 Lua coroutine
中去。具体说来,ngx_http_lua_socket_tcp_resume 会调用 u->prepare_retvals 把当前 Lua
函数的返回值先在 Lua 栈上准备好,然后调用 ngx_http_lua_run_thread,和先前入口时一样。
对一个 Lua coroutine 而言,其生命期就是由下面这一系列调用组成的:
lua_resume
lua_yield
lua_resume
lua_yield
...
当然,更具体的细节,你需要阅读相关的源码了。
Regards,
-agentzh