lua-users home
lua-l archive

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


The comment on the second line might explain why they are not garbage collected:
lua_pushvalue(hostLuaState, -1);        // Prevent the new thread from
being garbage collected

If a lua object (in this case a thread) is in a stack, being a key in
a table or being a value in a table, then it will not be garbage
collected. If you want it garbage collected:
1) Make sure it isn't on the stack anywhere (the stack of the main
state, or the stack of any threads)
2) Make sure it isn't the key or value of a key/value pair in a table

Removing a key from a table is the same as removing a key/value pair;
"x.y = nil" removes the "y" key and the associated value from "x".

Weak tables (http://www.lua.org/manual/5.1/manual.html#2.10.2) are an
exception to this rule, in that a table can be defined so that the
keys or values in the table are not counted as references to objects.
When a key or value of a key/value pair is garbage collected, then the
entire key/value pair is removed from the table automatically.

On 30/10/2007, Tom Miles <Tom@creative-assembly.co.uk> wrote:
> Hi,
>
> Having just started using Decda to debug my lua project I've noticed
> that my threads are never getting garbage collected.  I've searched the
> archives about this, and found some vaguely relevant posts, but none
> which can address my situation, so apologies if I've missed something.
>
> The states are set up thusly:
>
> state.m_state = lua_newthread(hostLuaState);
> lua_pushvalue(hostLuaState, -1);        // Prevent the new thread from
> being garbage collected
>
> // Add to our list of registered states, keeping a reference to the
> state so we can remove it later on
> m_RegisteredStates.push_back(ThreadRef(&state, hostLuaState,
> luaL_ref(hostLuaState, LUA_REGISTRYINDEX)));
>
> // Retrieve our lookup table from the global index table
> lua_pushstring(m_MainState, "lookup");
> lua_gettable(m_MainState, LUA_GLOBALSINDEX);
>
> // Set lookup[state.m_state] = &state
> lua_pushlightuserdata(m_MainState, state.m_state);
> lua_pushlightuserdata(m_MainState, &state);
>
> lua_settable(m_MainState, -3);
> // Remove the table from the stack
> lua_pop(m_MainState, 1);
>
>
> And "freed":
>
> CA_STD::LIST<ThreadRef>::iterator iter =
> std::find_if(m_RegisteredStates.begin(), m_RegisteredStates.end(),
> Finder(&state));
> if (iter != m_RegisteredStates.end())
>         luaL_unref((*iter).host, LUA_REGISTRYINDEX, (*iter).ref);
>
> This has been working for ages, but I realised I still used the lookup
> table, so I added:
>
> // Remove the state from the lookup table by setting
> lookup[state.m_state] = nil
> lua_pushstring(m_MainState, "lookup");
> lua_gettable(m_MainState, LUA_GLOBALSINDEX);
> lua_pushlightuserdata(m_MainState, state.m_state);
> lua_pushnil(m_MainState);
> lua_settable(m_MainState, -3);
>
> Which has added lots of random lockups and crashes within lua, usually
> during garbage colled.  It would seem that if I remove the value from my
> lookup table then states are being pulled from under my feet.  Or the
> lookup table removal code is corrupting the state somehow.
>
> So, a couple of questions:
> 1.  What am I doing wrong?
> 2.  If I use the state as a key in a table, does that count as a
> reference to the object as far as the GC is concerned?  If so, how do I
> remove a key from the table?
>
> Any help would be very greatfully recieved.
>
> Tom
>
>
>
> Tom Miles
>  creative assembly ----------------------------------------------------------------------------
>          DISCLAIMER
> This email is sent by The Creative Assembly Limited company No. 03425917, registered in England &Wales registered office 27 Great West Road, Middlesex, TW8 9BW, England. The contents of this e-mail and any attachments are confidential to the intended recipient and may also be legally privileged. Unless you are the named addressee (or authorised to receive for the addressee) of this email you may not copy, disclose or distribute it to anyone else. If you have received this email in error, please notify us immediately by e-mail on postmaster@creative-assembly.co.uk and then delete the email and any copies. The Creative Assembly Limited have made all reasonable efforts to ensure that this e-mail and any attached documents or software are free from software viruses, but it is the recipient's responsibility to confirm this.
>
>