lua-users home
lua-l archive

Confusion about globals

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


I am writing an application that hosts a small lua scripting environment. In my application, I want to load a script and then create a number of lua threads that will each have their own environment. Then my application can iterate over the list of threads and call each thread’s co-routine until all co-routines have completed. Each co-routine has its own “global” variable that will be unique. I have attached a trivial C file that duplicates the core functionality.

My issue is that the globals I declare in C and push to the thread stack are always nil when used in the lua script, but have the correct value when I retrieve them from C methods. Can someone tell me what I am doing wrong?

The only solution I have found is to reload the script in each thread – change #if 0 to #if 1. However, in my main application, I could be creating 10,000 or more lua threads. Re-loading the script in each thread is not ideal in this case.

I suspect that the method I invoke is using the global environment of the main thread instead of my sub-thread’s global environment. How would I change that behavior?

Marcus

-- main.c

#include "stdio.h"

#include "assert.h"

#include <lua.h>

#include <lauxlib.h>

#include <lualib.h>

int l_TestRoutine(lua_State *L)

{

//When I get the global variable id from the stack

//I get the correct value

lua_getglobal(L, "id");

luaL_checktype(L, -1, LUA_TNUMBER);

printf("Id: %d\n", (int)lua_tointeger(L, -1));

lua_pop(L, 1); // remove the id

return lua_yield(L, 0);

}

int main(int argc, char ** argv)

{

lua_State* LThreads[10];

/* initialize lua */

lua_State *L = lua_open();

luaL_openlibs(L);

int error = luaL_loadfile(L, "foo.lua");

printf("Error code: %d\n", error);

if (error != 0)

{

printf("Error: %s\n",lua_tostring(L,-1));

lua_pop(L, 1);

}

error = lua_pcall(L, 0, LUA_MULTRET, 0);

printf("Error code: %d\n", error);

if (error != 0)

{

printf("Error: %s\n",lua_tostring(L,-1));

lua_pop(L, 1);

}

lua_register(L, "Test", l_TestRoutine);

lua_pushinteger(L, 9999);

lua_setglobal(L, "id");

//now create many lua threads, each with it's own global variable

//and try to access the global

int i;

for (i = 0; i < 10; ++i)

{

LThreads[i] = lua_newthread(L);

//create our own copy of the globals table

lua_newtable( LThreads[i] ); //new globals table

lua_newtable( LThreads[i] ); //metatable

lua_pushliteral( LThreads[i], "__index" );

lua_pushvalue( LThreads[i], LUA_GLOBALSINDEX ); //original globals

lua_settable( LThreads[i], -3 );

lua_setmetatable( LThreads[i], -2 );

lua_replace( LThreads[i], LUA_GLOBALSINDEX ); //replace new globals

#if 0

error = luaL_loadfile(LThreads[i], "foo.lua");

printf("Error code: %d\n", error);

if (error != 0)

{

printf("Error: %s\n",lua_tostring(L,-1));

lua_pop(LThreads[i], 1);

}

error = lua_pcall(LThreads[i], 0, LUA_MULTRET, 0);

printf("Error code: %d\n", error);

#endif

lua_pushinteger(LThreads[i], i);

lua_setglobal(LThreads[i], "id");

//setup to call main for the first time

lua_getglobal(LThreads[i], "Main");

}

int j;

for (i = 0; i < 100; ++i)

{

for (j= 0; j < 10; ++j)

{

error = lua_resume(LThreads[j], 0);

if ((error != LUA_YIELD)

&& (error != 0))

{

printf("Error: %s\n",lua_tostring(LThreads[i], -1));

lua_pop(LThreads[i], 1);

//What should I do to handle an error?

assert(0);

}

}

}

/* teardown */

lua_close(L);

return 0;

}

-- Lua script

function Mine ()

print("called Mine")

end

function Main()

while true do

print (id)

Test()

end

end


AltStyle によって変換されたページ (->オリジナル) /