up vote -1 down vote favorite

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

75% accept rate

1 Answer

up vote 5 down vote

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.

link|flag
Doesn't my instancing function give the thread its own empty global state? – Reggie Feb 4 at 0:42
Nope; the state is shared; only the execution stack is fresh. See edit. – Norman Ramsey Feb 4 at 1:27
So how can I get this to work exactly? – Reggie Feb 4 at 1:51
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 Feb 4 at 4:06
When you don't solve a problem, you don't get an up vote! – Reggie Feb 6 at 6:25

Your Answer

 
get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.