tags:

views:

734

answers:

4

Is there a way to run Lua code from a C/C++ program at a more fine-grained level than a standard "lua_pcall" function call? Ideally I'd like to be able to loop over a list of low-level bytecode instructions (assuming it has such things) and run them one by one, so that I could write my own scheduler which had more control of things than just running a complete Lua function from start to finish.

The reason I want to do this is because I wish to implement C functions which Lua code can call which would cause the program to wait until a certain (potentially long-winded) action had completed before continuing execution. There would be a high proportion of such function calls in a typical Lua script, so the idea of rewriting it to use callbacks once the action has completed isn't really practical.

+1  A: 

Does the debugging interface help?

Jonathan Leffler
+6  A: 

Perhaps side-stepping the question, but you could use Lua coroutines rather than custom C stuff to wait until some event occurs.

For example, one coroutine could call a waitForEvent() function. In there, you can switch to another coro until that event occurs, then resume the first one. Take a look at the lua coro docs for more about that.

Jesse Rusak
This solution seems to have a lot of potential - particularly given that the C API can yield/resume coroutines itself.
andygeers
+3  A: 

Jder's suggestion to use coroutines will work very well if you can write those long waiting C routines using Lua's cooperative threading (explicit yield) feature. You'll still use lua_pcall() to enter Lua, but the entry point will be your coroutine manager function.

This only works though if the C routines don't do anything while they wait. If they are long running because they calculate something for example, then you need to run multiple OS threads. Lua is threadsafe -- just create multiple threads and run lua_open() in each thread.

From http://www.lua.org/pil/24.1.html

The Lua library defines no global variables at all. It keeps all its state in the dynamic structure lua_State and a pointer to this structure is passed as an argument to all functions inside Lua. This implementation makes Lua reentrant and ready to be used in multithreaded code.

You can also combine the two approaches. If you have a wrapper Lua function to start an OS thread, you can yield after you start the thread. The coroutine manager will keep track of threads and continue a coroutine when the thread it started has finished. This lets you use a single Lua interpreter with multiple worker threads running pure C code.

Ken Fox
+3  A: 

If you go the OS threading way, please have a look at Lua Lanes. I would see it the perfect solution to what you're trying to achieve (= throw one addon module to the mix and you'll be making clear, understandable and simple code with multithreading seamlessly built in).

Please tell us how your issue got solved. :)

akauppi
Thanks for the link - I'll definitely take a look into this
andygeers