lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Monday 01, Patrick Donnelly wrote:
> On Mon, Dec 1, 2008 at 12:01 PM, Sam Roberts <vieuxtech@gmail.com> wrote:
> >> My principle concern is whether it is considered legal to have a
> >> thread yield and then make a protected call using that thread before
> >> resuming it. We are allowed to push arguments in order to resume the
> >> thread but are we allowed to make function calls using that thread
> >> before doing so? My current implementation shows this is possible, but
> >> I question whether it is considered legal or safe. Essentially:
> >>
> >> testme:
> >> if (lua_resume(thread, lua_gettop(thread)) == LUA_YIELD)
> >> {
> >>  lua_getfield(thread, LUA_REGISTRYINDEX, "some_Lua_function");
> >>  lua_pushthread(thread);
> >>  if (lua_pcall(thread, 1, 0, 0) != 0)  /* <---- Is this legal?? */
> >>    fatal("...");
> >>  /* push other arguments to the thread */
> >>  goto testme;
> >> }
> >
> > Looks legal to me, but I can see why you wonder. I don't see why you use
> > the thread lua_State instead of the parent lua_State.
>
> This is because the main lua_State thread is resuming threads and is
> not available to execute the callback function. I thought perhaps I
> would need to make a simple throwaway thread for running each callback
> function but was hoping to avoid that by just using the yielded
> thread.

I would recommend a separate Lua thread for the callbacks or a pool of them if 
the callbacks need to do a lot of work.

One problem with calling a lua function using a yielded thread is that the 
thread can't be yielded a second time.  If the thread is yielded a second 
time you will not be able to resume to the first yield point, an 
error "cannot resume non-suspended coroutine" will be thrown.  Another 
problem is if the thread is resumed while it is running, this will mostlikely 
cause corruptions of the lua stack.  Normally you can't resume a 
non-yielded/running thread without getting that error, since thread's status 
will not be "LUA_YIELD".  This will not be the case if you make another call 
using a yielded thread, since the thread's status will still be "LUA_YIELD".

I have not verified those problems using code, just identified them from 
looking at the lua_yield/lua_resume/lua_pcall code.

Maybe it would be a good idea to throw an error (or at least an assertion) 
from lua_pcall/lua_call when they are called on yielded threads.

I hope that helps.

-- 
Robert G. Jakabosky