lua-users home
lua-l archive

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


I've spend the last several hours pouring through the archives trying
to understand the interaction between lua_resume, lua_yield, and
coroutines.  The problem I'm having is that when I have multiple
scripts running in separate threads, only the last created thread
seems to run correctly.

Here's my setup (more or less, minus error checking, a link to the
real code is below):

lua_State *L = NULL;

static void openlualibs(lua_state *);  // Open the common libraries

// This creates a global Lua state if necessary, then creates a new
Lua thread and loads the script into the thread.
lua_State *create_thread(const char *scr)
{
  lua_State *ret;

  if ( L == NULL )
  {
    L = luaL_newstate();
    openlualibs(L);
  }

  ret = lua_newthread(L);
  luaL_loadfile(ret, scr);

  return ret;
}

// Starts or resumes an Lua thread
int run_thread(lua_State *l)
{
  return lua_resume(l, 0);
}

Now, I have registered several functions that a Lua script can call
that will yield.  They all have a template similar to:

int cb1(lua_State *l)
{
  /* Process arguments */
  ...

  /* Yield */
  return lua_yield(l, 0);
}

Now, if I create multiple threads, such as:

lua_State *t1, *t2, *t3;

t1 = create_thread("test.lua");
t2 = create_thread("test.lua");
t3 = create_thread("test.lua");

Only t3 seems to run to completion.  Both t1 and t2 seem stuck at the
very same point.  Here's a snippet of the output from my test program.
 The "(N)" is the thread id (N = 0, 1, 2).  The FUNC_* are the names
of the callback functions being executed.

Starting tcon with tcon.lua
Tcon with id = 0 created.
(0) FUNC_GPIO_CLR_DIR:	0x00000007
Starting tcon with tcon.lua
Tcon with id = 1 created.
(1) FUNC_GPIO_CLR_DIR:	0x00000007
Starting tcon with tcon.lua
Tcon with id = 2 created.
(2) FUNC_GPIO_CLR_DIR:	0x00000007
(0) FUNC_GPIO_CLR_DIR:	0x00000007
(1) FUNC_GPIO_CLR_DIR:	0x00000007
(2) FUNC_WRITE:		REQ: 2 ADDR: 0x00000001 DATA: 0x00004e20
(0) FUNC_GPIO_CLR_DIR:	0x00000007
(1) FUNC_GPIO_CLR_DIR:	0x00000007
(2) FUNC_WRITE:		REQ: 2 ADDR: 0x00000002 DATA: 0x00004e20
[...snip...]
(0) FUNC_GPIO_CLR_DIR:	0x00000007
(1) FUNC_GPIO_CLR_DIR:	0x00000007
(2) FUNC_HALT
(0) FUNC_HALT
(1) FUNC_HALT

Note how (0) and (1) are all stuck until the end.  Thread (2) runs
just fine.  Then they all jump straight to the end of the script.  My
calls to lua_resume either return LUA_YIELD or 0 all the time (I never
get an error).  So I don't think I'm bumping up against the
C/coroutine boundary.

Now, I did find reference to independent global environments (here
http://lua-users.org/lists/lua-l/2003-10/msg00269.html).  I tried to
do what was suggested to create a new global table and replace the
local thread with the new table.  But instead I get the following
error:

Starting tcon with tcon.lua
Tcon with id = 0 created.
(0) FUNC_GPIO_CLR_DIR:  0x00000007
Starting tcon with tcon.lua
Tcon with id = 1 created.
PANIC: unprotected error in call to Lua API (tcon.lua:8: bad argument
#1 to 'bor' (string expected, got nil))

Now, the arguments to 'bor' are included from an external file with a
require statement.  I tried doing a local require (i.e. "tb =
require("tb")), but then I get an assertion from lua_pushlstring
('L->top < L->ci->top' failed).

This is my initial foray into coroutines.  Initially I used pthreads,
but I thought the overhead of threads wasn't worth it, so I'm trying
out this method.  This seems far more straightforward, cleaner, and
more efficient.  But I'm not getting something with using lua_resume
and lua_yield.  I'd prefer not to use Coco, and I'm not even sure it
is necessary in this case.  I'm sure I'm misunderstanding something.

I've created a tarball of my project including everything to build and
run the example.  You can download it at:

http://cid-3e6aa75359e23754.skydrive.live.com/self.aspx/Lua/test.tgz

The INDEP_TABLES define at the top of tcon_test.c inserts the code for
the independent global environments that I gathered from the Lua
mailing list.  It is disabled by default.

Any help would be appreciated,
Pete