| 
         | 
    ||
        
  | 
    
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
> > >
> > >
> > >
> >
> >
>