Skip to content
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
20 changes: 20 additions & 0 deletions regress/145-assertion-on-dead.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
_=[[
. "${0%%/*}/regress.sh"
exec runlua "$0" "$@"
]]
require"regress".export".*"

local co = coroutine.create(function()
coroutine.yield()
end)
coroutine.resume(co) -- kick off coroutine
coroutine.resume(co) -- resume a yield with no arguments
-- co is now dead

local cq = require"cqueues".new()
cq:attach(co)
check(cq:step())

say"OK"

23 changes: 17 additions & 6 deletions src/cqueues.c
Original file line number Diff line number Diff line change
Expand Up @@ -1982,10 +1982,22 @@ static cqs_status_t cqueue_resume(lua_State *L, struct cqueue *Q, struct callinf
}
} else {
nargs = lua_gettop(T->L);
if (status != LUA_YIELD) {
if (status == LUA_OK && lua_getstack(T->L, 0, &(lua_Debug){}) != 0) {
/* already running */
lua_pushliteral(L, "cannot resume non-suspended coroutine");
I->error.value = lua_gettop(L);
err_setthread(L, I, T);
goto defunct;
} else if ((status != LUA_OK && status != LUA_YIELD) || nargs == 0) {
/* dead coroutine */
lua_pushliteral(L, "cannot resume dead coroutine");
I->error.value = lua_gettop(L);
err_setthread(L, I, T);
goto defunct;
} else if (status == LUA_OK) {
/* initial */
nargs -= 1;
assert(nargs >= 0);
}
} /* else normal yield */
}

timer_del(Q, &T->timer);
Expand Down Expand Up @@ -2294,9 +2306,8 @@ static int cqueue_wrap(lua_State *L) {
luaL_checktype(L, 2, LUA_TFUNCTION);

newL = lua_newthread(L);
for (i = 2; i <= top; i++) {
lua_pushvalue(L, i);
}
lua_insert(L, 2);
luaL_checkstack(newL, top - 1, "too many arguments");
lua_xmove(L, newL, top - 1);

thread_add(L, Q, &I, -1);
Expand Down