[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Why I can't resume a coroutine created in a previous call to a C function?
- From: Thiago Padilha <tpadilha84@...>
- Date: Wed, 8 Oct 2014 07:39:04 -0300
Andrew
It is as I suspected then, thanks for your in-depth explanation
As I said in my initial post, there's no C call frame between the
`resume()` and `yield()` calls, so I did some extra investigation and
digged the real problem: I was invoking `pcall` inside the coroutine,
which is not supported.
Anyway, I managed to work around the issue by adapting a snippet shown
by Roberto Ierusalimsch in another mailing list post
:http://lua-users.org/lists/lua-l/2004-10/msg00142.html
Thank you all for the help
Thiago
On Tue, Oct 7, 2014 at 12:46 AM, Andrew Starks <andrew.starks@trms.com> wrote:
>
>
> On Mon, Oct 6, 2014 at 7:50 PM, Thiago Padilha <tpadilha84@gmail.com> wrote:
>>
>> Philipp
>>
>> I imagined that the lua VM maintained a separate "virtual" call stack
>> for every lua chunk, not only coroutines. What you mean is that every
>> lua call frame(except for those in coroutines) is also a C call frame?
>> If so, I understand the problem.
>>
>> Thanks for the explanation\
>
>
> I don't think that is right. Not every lua call is a C call frame and C call
> frames may happen in any Lua thread.
>
> Because I'm dealing with threads in my current project, and because my
> knowledge is new and fragile, I'd like to practice by providing my
> understanding:
>
> In a Lua program's execution, C frames and lua frames are mixed within the
> main Lua stack, as functions call other functions that are in either.
>
> C --> (L --> L --> L) --> C --> (L --> L) --> C ...
>
> Each call into and out of Lua is a black box, if viewed from C and ignoring
> internal Lua implementation details.
>
> When a coroutine is fired by the resume function, it appears as the final
> call in Lua's call stack, with the last entry being a pointer to the last
> executed position (yield or the first frame is made by calling the main
> function if yield hasn't happened) in the resumed thread's call stack. More
> function calls, either in C or Lua, may happen, including additional calls
> to resume. Therefore there are potentially dozens of Lua threads, each
> possibly containing a C function call.
>
> As the Lua program is creating these stack entries in each of the thread's
> stacks, as `resume` is used to jump to different sacks, additional calls
> into C functions may appear.
> From C, ignoring internal calls into the Lua API, these "thread switches"
> look like:
>
> 1: call C function
> 2: call lua_library_function
> <<hidden from view: dozens of Lua function calls and 3 calls to resume
> happen. Now we're on thread ??? >>
> 3: call C function
> 4: call lua_library
> <<a yield happens, which brings us back to some point around 2.5... we
> later return and...>>
> 5: call C_function ...
>
> When the yield happens, Lua is able to preserve the stack (locals, upvalues,
> current line, etc) between the yield and the calling resume, but only if no
> C functions were added between the last resume and the next yield. This is
> because in C, there is no mechanism that can parrot what coroutines do, as
> you know and so Lua stops execution to prevent it.
>
> In 5.2, you can pass a pointer to a C callback / continuation function and a
> context object into the 'k' calling variants
> (lua_pcallk/lua_callk/lua_yieldk). In cases where Lua finds these calls on
> the call stack, the original C functions are destroyed and in Lua, they are
> replaced with the context object and a new call to the continuation
> function, which then receives context object, (upvalues, locals from the
> main function and the return values from yield for lua_yieldk). My details
> on this (and all other) part(s) are probably wrong, however...
>
>
> Anyway, I look forward to the corrections/clarifications/affirmations. All
> that I have achieved in life, I owe to being wrong....
>
>
> -Andrew
>
>
>