lua-users home
lua-l archive

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


On Wednesday 15 February 2006 16:35, David Given wrote:
[...]
> Looking at the Lua code, I can't actually figure out how anything works in
> the first place. In (Lua 5.0) lua_yield(), I get the boundary error if
> nCcalls>0. But luaD_call() always increments nCcalls while doing the call,
> and as far as I can tell, all cases where C is calling Lua pass through
> there; so how can it ever *be* zero?

I've done some more investigation using Lua 5.0 without the patch. (To try and 
figure out what's happening.)

My code use tolua, which BTW is incredibly nice. I have exactly two places 
where I'm calling lua_pcall, and they're both in the same function. The code 
looks like this:

callback()
{
	count++
	lua_getglobal(L, "queuetask")
	lua_pcall(L)
	count--

	if (count == 0)
	{
		count++
		lua_getglobal(L, "schedule")
		lua_pcall(L)
		count--
	}
}

That is, callback() calls the queuetask() function in Lua. This adds a new 
function onto my task list. On return, if nobody's using Lua, then I call my 
scheduler. This pulls the first thing off the task list, and if it's a 
function turns it into a coroutine. Then it resumes it. When the coroutine 
yields, the scheduler returns back to the function above.

The *first* time the scheduler is called, this happens:

* Scheduler pulls a function off the task list.
* Scheduler turns it into a coroutine with coroutine.create() and replaces it 
on the task list.
* Scheduler resumes it.
* Coroutine does some work.
* Coroutine calls coroutine.yield.
* 'Attempt to yield across yada yada'.
* Coroutine dies.
* Scheduler resumes, and sees dead coroutine.

Creating the coroutine, resuming it, and then trying to yield from it all 
occur in the *same* invocation of Lua. Why is this failing?

Looking at ldo.c, I see this:

void luaD_call (lua_State *L, StkId func, int nResults) {
...
  if (++L->nCcalls >= LUA_MAXCCALLS) {
...
  }
  firstResult = luaD_precall(L, func);
  if (firstResult == NULL)  /* is a Lua function? */
    firstResult = luaV_execute(L);  /* call it */
...
  L->nCcalls--;
...
}

This functions appears, from what I can tell, to be the bottleneck through 
which all invocations of Lua pass. It is not possible to execute Lua, from 
outside Lua, without passing though the above code. nCcalls is initialised to 
zero, therefore barring overflow, there should be no way that it can be zero 
while luaV_execute() is being called.

Since lots of people (including me) have had this all working, I'm obviously 
wrong. Can anybody point out what I'm missing? Please?

-- 
+- David Given --McQ-+ "I must have spent at least ten minutes out of my
|  dg@cowlark.com    | life talking to this joker like he was a sane
| (dg@tao-group.com) | person. I want a refund." --- Louann Miller, on
+- www.cowlark.com --+ rasfw

Attachment: pgpL7NPjHCr1U.pgp
Description: PGP signature