views:

83

answers:

1

When I have two scripts with the same function names and arguments run in different threads with SUPPOSEDLY different environments, the second thread ends up overwriting the definitions of the first and the first thread's state gets garbage collected!

// My thread instancing function
lua_State* LuaInstance::RunInstance(const std::string& fileName)
{
  lua_State* L = lua_newthread(m_state); 

  // Give new thread it's own global table
  lua_newtable(L);
  lua_newtable(L);
  lua_pushliteral(L, "__index");
  lua_pushvalue(L, LUA_GLOBALSINDEX);  // Original globals
  lua_settable(L, -3);
  lua_setmetatable(L, -2);
  lua_replace(L, LUA_GLOBALSINDEX);    // Replace LB's globals

  // Run script off new thread
  luaL_dofile(L, fileName.c_str());

  return L;
}

I'm basically trying to get it so that I can call multiple scripts like this (For a game engine):

-- Script 1
function Init(self)
  -- Do some stuff
end


-- Script 2
function Init(self)
  -- Do some other stuff
end
+5  A: 

As it says in the manual, a the state created by new thread shares global state with other threads. If you want per-thread storage you'll have to create a special key to use in the registry.

From the manual (emphasis mine):

lua_State *lua_newthread (lua_State *L);

Creates a new thread, pushes it on the stack, and returns a pointer to a lua_State that represents this new thread. The new state returned by this function shares with the original state all global objects (such as tables), but has an independent execution stack. There is no explicit function to close or to destroy a thread. Threads are subject to garbage collection, like any Lua object.

Norman Ramsey
Doesn't my instancing function give the thread its own empty global state?
Reggie
Nope; the state is shared; only the execution stack is fresh. See edit.
Norman Ramsey
So how can I get this to work exactly?
Reggie
This really calls for a separate question, but you could try returning the init function, e.g., `return function(self) ... do some stuff ... end`. Then you can call `dofile("script1.lua")(self)`. Have you figured out how the upvote button works?
Norman Ramsey
When you don't solve a problem, you don't get an up vote!
Reggie