bugfix: calling ngx.thread.wait() on a user thread object that is already waited (i.e., already dead) would hang forever. thanks Sam Lawrence for the report.

This commit is contained in:
Yichun Zhang (agentzh) 2013-10-18 14:57:03 -07:00
Родитель dad8ba3ab8
Коммит 0f3c249a9a
2 изменённых файлов: 71 добавлений и 1 удалений

Просмотреть файл

@ -169,8 +169,23 @@ ngx_http_lua_uthread_wait(lua_State *L)
return nrets;
case NGX_HTTP_LUA_CO_DEAD:
dd("uthread already waited: %p (parent %p)", sub_coctx,
coctx);
if (i < nargs) {
/* just ignore it if it is not the last one */
continue;
}
/* being the last one */
lua_pushnil(L);
lua_pushliteral(L, "already waited");
return 2;
default:
/* still alive */
dd("uthread %p still alive, status: %d, parent %p", sub_coctx,
sub_coctx->co_status, coctx);
break;
}

Просмотреть файл

@ -1223,3 +1223,58 @@ ok
--- error_log
lua user thread aborted: runtime error: [string "content_by_lua"]:5: f done
=== TEST 21: waiting on a dead coroutine
--- config
location /lua {
content_by_lua '
function f()
ngx.say("hello in thread")
return "done"
end
local t, err = ngx.thread.spawn(f)
if not t then
ngx.say("failed to spawn thread: ", err)
return
end
ngx.say("thread created: ", coroutine.status(t))
collectgarbage()
local ok, res = ngx.thread.wait(t)
if not ok then
ngx.say("failed to run thread: ", res)
return
end
local ok, res = ngx.thread.wait(t)
if not ok then
ngx.say("failed to run thread: ", res)
return
end
ngx.say(res)
';
}
--- request
GET /lua
--- stap2 eval: $::StapScript
--- stap eval: $::GCScript
--- stap_out
create 2 in 1
spawn user thread 2 in 1
terminate 2: ok
delete thread 2
terminate 1: ok
delete thread 1
--- response_body
hello in thread
thread created: zombie
failed to run thread: already waited
--- no_error_log
[error]