Hmmm. Previous posts on this sort of topic have stated that you can
just remove the thread handle from the stack, hence my previous
posts. To be honest, I'm not sure what the creation of the local
environment acheives? Could you explain that part for me?
Thanks,
Tom
-----Original Message-----
From: lua-bounces@bazar2.conectiva.com.br
[mailto:lua-bounces@bazar2.conectiva.com.br]On Behalf Of Julien Hamaide
Sent: 07 June 2006 17:34
To: Lua list
Subject: Re: About lua_newthread
The problem with this approach is that the thread will never be garbage
collected as lua_newthread push a thread handle on the main thread stack.
So at the end of this call, you still have the thread handle on the
stack.
I also see that you use the global table to store thread function. Pay
attention that if 2 thread have functions with the same name, they will
collide.
I use same kind of thing for a game, this is my approach for both
liveness of thread and local space :
In my Thread constructor :
// master state is my main thread
ThreadState = lua_newthread( master_state );
// prevent thread from being garbage collected
lua_pushvalue( master_state, -1 );
ThreadReferenceIdentifier = luaL_ref( master_state,
LUA_REGISTRYINDEX );
//Create a local environment with a link to global environment via
__index metamethod
lua_newtable( master_state );
lua_pushvalue( master_state, -1 );
lua_setmetatable( master_state, -2 ); //Set itself as metatable
lua_pushvalue( master_state, LUA_GLOBALSINDEX );
lua_setfield( master_state, -2, "__index" );
lua_setfenv( master_state, -2 );
lua_pop( master_state, 1 );
and in the destructor :
luaL_unref( master_state, LUA_REGISTRYINDEX,
ThreadReferenceIdentifier );
If you have any questions about it, don't hesitate
Julien Hamaide
Lead Programmer
10Tacle Studios Belgium
Tom Miles a écrit :
> Thanks for the speedy response.
>
>
>
> >> Can you show us how you initialize your thread??
>
> I am using an approach similar to the one in Game Programming Gems 5,
> where I have a manager object that controls the main state and dishes
> out threads when requested. I.e.
>
> //
>
> static void CreateThread(State & state)
> {
> if (m_MainState == NULL)
> {
> m_MainState = luaL_newstate();
> luaL_openlibs(m_MainState);
>
> luaL_openlib(m_MainState, "Script", scriptLib, 0);
> }
>
> state.m_state = lua_newthread(m_MainState);
>
> // save a pointer to the thread manager object in the global
> table
> // using the new thread's vm pointer as a key
> lua_pushlightuserdata(m_MainState, state.m_state);
> <--- Is this causing a problem?
> lua_pushlightuserdata(m_MainState, &state);
> lua_settable(m_MainState, LUA_GLOBALSINDEX );
> }
>
> static void ReleaseThread(State & state)
> {
> int stackSize = lua_gettop(m_MainState);
> for (int n=0; n<stackSize; ++n)
> {
> // This check should be: lua_isthread() &&
> lua_tothread() == state.m_state
> if (lua_touserdata(m_MainState, n) == state.m_state)
> {
> lua_remove(m_MainState, n);
> break;
> }
> }
> // For the time being, set the value of the key (the state we
> are removing) in our map to be nil
> lua_pushlightuserdata(m_MainState, state.m_state);
> lua_pushnil(m_MainState);
> lua_settable(m_MainState, LUA_GLOBALSINDEX);
>
> // There is also code to close down lua if we have released
> the last thread here
> }
>
> >> If you use a weak value table, the entry will be deleted when the
> object
> >> is collected.
>
> >> Just put "v" in field __mode of the metatable of your table. If you
> want
> >> weak key, just put "k".
>
> As you can see, I am using the globals table, but I suppose I could
> create a weak table especially for the job instead.
>
> > Tom
> >
> > -----Original Message-----
> > *From:* lua-bounces@bazar2.conectiva.com.br
> > [mailto:lua-bounces@bazar2.conectiva.com.br]*On Behalf Of* Raymond
> Jacobs
> > *Sent:* 18 May 2006 16:20
> > *To:* Lua list
> > *Subject:* Re: About lua_newthread
> >
> > When you are done with a thread (when lua_resume returns and it's
> > not a yield), you should remove the thread directly from the
> > stack, this will remove the reference to it and it can then be
> > garbage collected (its a pain I know =/).
> >
> > another method which I've not yet done but should work, is to
> > create a new thread, create a lua reference to it (using lua_ref)
> > then pop it off the stack immediately (so it doesn't get buried),
> > and later when you are done with it, destroy the reference
> > (lua_unref) and that should allow it to be GC'd
> >
> > hope that helps,
> >
> > Raymond Jacobs
> > Owner,
> > Ethereal Darkness Interactive
> >
> >
> > On 5/18/06, *mos* <mmosquito@163.com <mailto:mmosquito@163.com>>
> > wrote:
> >
> >
> > Hi
> >
> > in lua5.1 manual:
> >
> > lua_newthread
> > lua_State *lua_newthread (lua_State *L);
> > There is no explicit function to close or to destroy a
thread.
> > Threads are
> > subject to garbage collection, like any Lua object
> >
> > I don't understand this , for example like Npc in a
game
> >
> > function AI()
> > while(true) do
> > walkto(A)
> > walkto(B)
> > ...
> > walkto(Z)
> > end
> > end
> >
> > I bind each npc with a lua_State by lua_newthread
> >
> > but the npc will die and i should close the
lua_State ,
> > but I can
> > not.
> > what can I do ? or some better suggestion ?
> >
> > Best Regards
> > mos
> >
> >
> >
>
>