-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
According to the documentation here: https://github.com/openresty/lua-nginx-module#coroutinecreate
coroutine.create can be used in init_by_lua*, header_filter_by_lua*, body_filter_by_lua*, because OpenResty would replace OpenResty's coroutine with the Lua native coroutine in these phases, which can not yield.
code:
lua-nginx-module/src/ngx_http_lua_coroutine.c
Lines 336 to 375 in d34d3c5
| { | |
| const char buf[] = | |
| "local keys = {'create', 'yield', 'resume', 'status', 'wrap'}\n" | |
| #ifdef OPENRESTY_LUAJIT | |
| "local get_req = require 'thread.exdata'\n" | |
| #else | |
| "local getfenv = getfenv\n" | |
| #endif | |
| "for _, key in ipairs(keys) do\n" | |
| "local std = coroutine['_' .. key]\n" | |
| "local ours = coroutine['__' .. key]\n" | |
| "local raw_ctx = ngx._phase_ctx\n" | |
| "coroutine[key] = function (...)\n" | |
| #ifdef OPENRESTY_LUAJIT | |
| "local r = get_req()\n" | |
| #else | |
| "local r = getfenv(0).__ngx_req\n" | |
| #endif | |
| "if r ~= nil then\n" | |
| #ifdef OPENRESTY_LUAJIT | |
| "local ctx = raw_ctx()\n" | |
| #else | |
| "local ctx = raw_ctx(r)\n" | |
| #endif | |
| /* ignore header and body filters */ | |
| "if ctx ~= 0x020 and ctx ~= 0x040 then\n" | |
| "return ours(...)\n" | |
| "end\n" | |
| "end\n" | |
| "return std(...)\n" | |
| "end\n" | |
| "end\n" | |
| "package.loaded.coroutine = coroutine" | |
| #if 0 | |
| "debug.sethook(function () collectgarbage() end, 'rl', 1)" | |
| #endif | |
| ; | |
| rc = luaL_loadbuffer(L, buf, sizeof(buf) - 1, "=coroutine_api"); | |
| } |
And also here: https://github.com/openresty/lua-resty-core/blob/master/lib/resty/core/coroutine.lua#L4-L24
Now the problem is: If I call coroutine.create in init_worker phase, match the
if ctx ~= 0x020 and ctx ~= 0x040 then
return ours(...)
endAnd then return the OpenResty's coroutine. (ctx of init_worker is 0x0100)
This would cause ean rror API disabled in the context of init_worker_by_lua* because check here:
lua-nginx-module/src/ngx_http_lua_coroutine.c
Line 117 in d34d3c5
| ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); |
So I suggest returning the Lua native coroutine in the init_worker phase, change like
if ctx ~= 0x020 and ctx ~= 0x040 and ctx ~= 0x0100 then
return ours(...)
endThis may allow users to use native Lua coroutine in init_worker phase.