[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: problem with lua_resume/lua_lock
- From: "Zimmermann, Maik" <Zimmermann@...>
- Date: Wed, 7 Aug 2002 15:32:40 +0200
Hi there,
I was playing around with lua_lock / lua_unlock (lua-5.0 work0, Windows)
using the following lua_user.h:
<<<
#include <windows.h>
#undef LoadString
#define LUA_USERSTATE CRITICAL_SECTION cs;
#define lua_lock(L) EnterCriticalSection(&((L)->cs))
#define lua_unlock(L) LeaveCriticalSection(&((L)->cs))
#define lua_userstateopen(L) InitializeCriticalSection(&((L)->cs))
Testing it with the following lua code the interpreter freezed:
<<<
function test()
local i = 0
while 1 do
i = i + 1
coroutine.yield(i)
end
end
co = coroutine.create(test)
for i = 1, 10 do
print(co())
end
>>>
I think I have found the problem in lua_resume (ldo.c):
The call
status = luaD_runprotected(co, resume, &ud.err);
in lua_resume() ends up in luaD_precall(), which tries to lua_unlock() the
never locked coroutine
state before the actual coroutine function is called.
I changed lua_resume() to
LUA_API int lua_resume (lua_State *L, lua_State *co) {
CallInfo *ci;
struct ResS ud;
int status;
lua_lock(L);
ci = co->ci;
if (ci == co->base_ci) /* no activation record? ?? */
luaG_runerror(L, "thread is dead - cannot be resumed");
if (co->errorJmp != NULL) /* ?? */
luaG_runerror(L, "thread is active - cannot be resumed");
if (L->errorJmp) {
setobj(&ud.err, L->errorJmp->err);
}
else
setnilvalue(&ud.err);
lua_lock(co); /* MZ: added
this line */
status = luaD_runprotected(co, resume, &ud.err);
lua_unlock(co); /* MZ: added this
line */
if (status == 0)
move_results(L, co->top - ud.numres, co->top);
else {
setobj(L->top++, &ud.err);
}
lua_unlock(L);
return status;
}
wich seems to solve the problem but I might have overlooked something.
My knowlage of the internal is not realy good. Does everybody know if
this change breaks something?
Best regards
Maik Zimmermann