lua-users home
lua-l archive

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


Ben Sunshine-Hill wrote:
> Apologies if I'm missing something obvious, but under this patch, what
> features are in place to prevent resource leaks with a C function that
> allows yielding after having locked a resource, and then is never
> resumed (thread is GCed)? Obviously, one could stick a userdata on the
> stack with a custom __gc for cleanup, but is there a less roundabout
> way?

Excellent comment!

Well, most of the time you have resources wrapped with a userdata, anyway.
But then you still have the problem of explicitly vs. implicitly freeing
resources. E.g. a thread is timed out and you want those sockets hidden
deep down in the thread stack closed _now_ and not when the GC kicks in.

I've given this a bit of thought before and came up with this idea
(snippet from the TODO list at the end of the Wiki page):

| A way to resume a coroutine and immediately throw an error. This can
| be used to involuntarily stop a coroutine and still give it a chance
| to clean up its state and resources with a pcall wrapper. This is
| useful for timeouts and related stuff and avoids having special case
| code in every yielding function.
| An extension to the C API is straightforward (a 10 line change to give
| lua_resume(L, -1) a meaning).
| But I still have no idea for a nice Lua API other than introducing
| a new coroutine.eresume(co, err) function.

I've experimentally added lua_resume(L, -1) in my codebase. Alas, it
slows down the regular code path a tiny bit. Probably still acceptable.

But the Lua API issue remains: coroutine.eresume() feels so un-orthogonal.

And error([co,] err) just doesn't cut it. The coroutine may continue
running when pcall has caught the error! This is more like a resume,
not like a non-local throw.

Does any other language have such a concept? I know that everyone is
working around this issue with native threads, since you cannot reliably
kill them. Lots of 'if (flag) { dealloc(); pthread_exit(); }' littered all
over the source. Not pretty -- I really want to avoid this.