[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Coroutines & C boundaries
- From: David Given <dg@...>
- Date: Wed, 15 Feb 2006 23:49:43 +0000
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:
pgpRu0AYeQ89V.pgp
Description: PGP signature