lua-users home
lua-l archive

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


Hi list

I'm writing a single threaded program that is essentially just a
mainloop to create and resume Lua threads. These threads then call C
functions for input and output (receive() and send()), which will try
to get/send data in non-blocking mode, and if not possible they'll
lua_yield() and register with the mainloop to be resumed when new
input/output is possible.

The upshot of this design is that the Lua side becomes very easy to
write. It will almost seem like the Lua functions are run in their own
"thread" and send() and receive() block until they're done. Only if you
access global or shared variables do you need to know what is actually
going on.

Side question: Surely someone else must have thought of this design
before me, but does it have a name? I've heard of green threads, but
doesn't that imply preemptive yielding of functions, like yielding
every x instructions?

These threads have some data associated with them, that needs to be
flushed/closed/freed when the Lua function ends or throws an error.

One solution would be to store the data and destructors with the state
in an external struct like so:

typedef int (*error_handler)(lua_State *T, void *thread_data);
typedef int (*destructor)(lua_State *T, void *thread_data);
struct myThread {
        lua_State *T;
        error_handler err;
        destructor destruct;
        void *thread_data;
};

Recently I thought of another solution I think is a bit more elegant
although it might be abuse of Lua. What I do is to push the thread
specific data to the Lua thread before the Lua function to
lua_resume(). Once the thread is started and yielded again these won't
appear on the stack, but as soon the function ends or errors they're
back on the stack where I need them.

This is all very good and works fine except for one situation: Say a
thread is yielded while waiting for data, but in the meantime the
connection is closed or some other error happens and I want to
immediately stop execution of the thread and clean up the data
associated with it. The problem is that now I can't get to the data I
pushed to the stack before starting it, so what I really need is some
way to resume the thread, but throw an error immediately. I've been
looking through the manual several times now, but I can't figure out
how to do that. Am I just blind or is there a good reason this isn't
possible?

PS. Thank you for reading this far and sorry for the long post. I'm
sure you can tell I'm not a computer scientist but just a hobby hacker
who fell in love with the beautiful minimalism of Lua

/Emil