lua-users home
lua-l archive

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


Title: RE: About lua_newthread

Thanks for all that.  I didn't realise that functions added to one thread are added to the global environment.  Seems a bit funny, but my brain has been trained into thinking "C++" for 10 years :)

> -----Original Message-----
> From: lua-bounces@bazar2.conectiva.com.br
> [mailto:lua-bounces@bazar2.conectiva.com.br]On Behalf Of
> Julien Hamaide
> Sent: 08 June 2006 10:26
> To: Lua list
> Subject: Re: About lua_newthread
>
>
> As you know, function in lua is just a variable. When you create a
> thread, all global variable and functions from it are put inside the
> global environment, which by default is the global environment of the
> main state. So, for example, if a threads declare a global function
> Update, a variable Update is create in LUA_GLOBALINDEX table
> and is then
> available to all threads. The problem is if another thread
> create also a
> function Update, it overwrites the previous one, as the value of
> variable Update is just replace.
>
> So by creating a local environment, each thread global are not copied
> inside main state global.
> The __index tricks still allow threads to access all global
> field that
> had been registered ( such as library ). __index is triggered when a
> field is not found in current table.
>
> If you want, just make a test, create 2 script with same name
> function,
> you'll see that the function is overwritten
>
> Julien
>
> Tom Miles a écrit :
>
> > 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
> > >
> > >
> > >
> >
> >
>