lua-users home
lua-l archive

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


It was thus said that the Great Luna once stated:
> Hi all,
> 
> I want give Lua code access to functions implemented by my C program
> that can block while they wait for something to be ready, but the
> program might also want to do other things while it's waiting, and I'd
> rather not make that happen using OS threads. Coroutinies seem like
> they're well suited for that task at first, because when I want to run a
> Lua function I can just wrap it in a thread that can yield first, and
> then the blocking function that the Lua code can call can just yield
> something indicating it's waiting, and the thread can be resumed by the
> program when desired.
> 
> That stops working, though, if the Lua code itself uses coroutines. If
> the blocking function is called within a thread other than the one that
> the main program has created, then when it yields, control will just go
> to another place in the Lua script. I've searched through documentation
> and haven't found a way that I can pause a Lua thread and give back
> control to the program regardless of the state of that thread, even
> though it feels like something like that should be possible.
> 
> Am I missing something?

  I don't know.  I do have code that may do what you want, but it involves
several modules working together, and is operating system specific.  I use
it mostly for network services.

  For a network service, the main loop [1] will handle network [2] events
[3].  For a new TCP/TLS [4] connection [5][6], a new coroutine will be
created to handle the connection.  This coroutine is then put into a run
queue and after checking (and handling) each event, this run queue is run,
wherein each coroutine will run until either it finishes, or it calls a
"blocking" function (like read() or write()) where in will explicitly yield
back to the main coroutine.  An example of this can be seen starting with
line 52 of [5].  I also support timeouts that will take a waiting coroutine
(for an I/O event) and just run it with an error code---this is mostly used
for input, by the way.

  I'll admit, the code is a bit hard to follow as it flows through a bunch
of modules.  There are other, better documented and maybe easier to use
modules that exist, but it would help if you can mention the OS you are
using so appropriate recommendations can be made.

  -spc

[1]	A framework to handle events, usually network events.  This runs in
	the main coroutine:
	https://github.com/spc476/lua-conmanorg/blob/master/lua/nfl.lua

[2]	A module that interfaces to the Berkely sockets API:
	https://github.com/spc476/lua-conmanorg/blob/master/src/net.c

[3]	A module that wraps select(), poll(), kqueue() or epoll(), depending
	upon the Unix operating system:
	https://github.com/spc476/lua-conmanorg/blob/master/src/pollset.c

[4]	A module that wraps libtls:
	https://github.com/spc476/lua-conmanorg/blob/master/src/tls.c

[5]	A module to handle TCP conncetions via the framework [1].  Each
	connection is handle via a coroutine:
	https://github.com/spc476/lua-conmanorg/blob/master/lua/nfl/tcp.lua

[6]	A module to handle TLS connections via the framework [1]. It has
	a similar API to [5]:
	https://github.com/spc476/lua-conmanorg/blob/master/lua/nfl/tls.lua