lua-users home
lua-l archive

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



On 31-Oct-06, at 3:56 AM, subatomic wrote:

Thumbing through the 5.1 ref manual, I tried this instead of luaL_ref:

      lua_setfield(L, LUA_GLOBALSINDEX, "bok");

and it seems to work (my thread is not garbage collected).

I don't like the string lookup, and I also wonder about the best way to generate a unique string-per-thread (just convert the thread ptr to string??).  seems hacky, I really liked the luaL_ref way of doing this...   I'd still be very interested to hear  what people know about all this, and what way (other than the stack) should I ref my threads to save them from the perils of the GC.

I took a glance at your code, but it's not clear to me what might be going wrong. I'd check to make sure that the thread is still in the registry where you put it, in case perhaps luabind is playing some games with the registry. (lua_rawgeti(L, LUA_REGISTRYINDEX, thread_reference) will push it onto the stack.)

A couple of notes, though.

First, I think you should be less nervous about just keeping your threads on the Lua stack. It's not the C stack, and its capacity is pretty well what you want it to be (it's just a malloc()'d array); use lua_checkstack or luaL_checkstack to expand it to an appropriate size). You could call lua_gettop(L) after you push the thread onto the stack in order to get the stack index, which would work like your thread_reference, and you can delete a single element from the stack with something like:

  lua_pushnil(L);
  lua_replace(L, index);

That will preserve stack indexes. You could also thread a free list through the deleted entries, luaL_ref() style, by pushing an integer instead of nil:

  lua_pushinteger(L, mFree);
  lua_replace(L, index);
  mFree = index;

  // To make a new thread:
  lua_newthread(L);
  if (mFree != 0) {
int tmp = mFree; mFree = lua_tointeger(L, mFree); lua_replace(L, tmp);
  }

The other thing is that there is only one garbage collector. You cannot garbage collect threads independently. When you call:

  lua_gc(some_state, GCCOLLECT, 0);

it will garbage collect the entire Lua universe to which some_state belongs, using some_state to call finalizers. (It also will guarantee that some_state is not itself collected, in case there is no other reference to it; other than that, it doesn't make that much difference which state you use, although I'd tend to use the main state.)

The comment about having to collect actors before their thread is deleted suggests that something is wrong with your finalizer model, if you actually experienced the crash to which you refer.