Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: supported wait any uthreads for ngx.thread.wait #2170

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/ngx_http_lua_uthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ ngx_http_lua_uthread_spawn(lua_State *L)
static int
ngx_http_lua_uthread_wait(lua_State *L)
{
int i, nargs, nrets;
int i, nargs, nrets, dead_count;
lua_State *sub_co;
ngx_http_request_t *r;
ngx_http_lua_ctx_t *ctx;
Expand All @@ -129,6 +129,8 @@ ngx_http_lua_uthread_wait(lua_State *L)
return luaL_error(L, "at least one coroutine should be specified");
}

dead_count = 0;

for (i = 1; i <= nargs; i++) {
sub_co = lua_tothread(L, i);

Expand Down Expand Up @@ -172,11 +174,11 @@ 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);
dd("uthread already waited: %p (parent %p), dead/total: %d/%d",
sub_coctx, coctx, dead_count + 1, nargs);

if (i < nargs) {
/* just ignore it if it is not the last one */
if (++dead_count < nargs) {
/* just ignore it if not all threads are dead */
continue;
}

Expand Down
51 changes: 51 additions & 0 deletions t/098-uthread-wait.t
Original file line number Diff line number Diff line change
Expand Up @@ -1340,3 +1340,54 @@ GET /lua
at least one coroutine should be specified
--- no_error_log
[crit]



=== TEST 24: wait any uthreads
--- config
location /lua {
content_by_lua '
local function f(seconds, tag)
-- ngx.say("hello in thread")
ngx.sleep(seconds)
return tag, seconds
end
local threads_args = {
{ 1, 't1 wait 1 seconds'},
{ 0.2, 't2 wait 0.2 seconds'},
{ 3, 't3 wait 3 seconds'},
{ 2, 't4 wait 2 seconds'},
{ 0.5, 't5 wait 0.5 seconds'},
}
local threads = {}
for i, args in ipairs(threads_args) do
local t, err = ngx.thread.spawn(f, args[1], args[2])
if not t then
ngx.say("failed to spawn thread: ", err)
break
end
threads[i] = t
end

for i = 1, #threads + 1 do
local ok, res = ngx.thread.wait(unpack(threads))
if not ok then
ngx.say("failed to run thread: ", res)
break
end

ngx.say(i, ": ", res)
end
';
}
--- request
GET /lua
--- response_body
1: t2 wait 0.2 seconds
2: t5 wait 0.5 seconds
3: t1 wait 1 seconds
4: t4 wait 2 seconds
5: t3 wait 3 seconds
failed to run thread: already waited or killed
--- no_error_log
[error]