An often neglected, but quite important aspect of __close is its
interaction with coroutine termination. pcall + call don't do that.
Here is an idea for how to handle the problem of resource cleanup of
a (suspended) coroutine using existing mechanisms:
1. There is a global table that maps coroutine --> stack-of-cleanup-tasks.
These tasks are pushed/popped from the stack as the coroutine runs.
2. Each cleanup task holds a reference to the cleanup function (I think
they can be weak if needed).
3. In a coroutine, use the pcall+call method whenever a resource is
created that needs to be cleaned up; the pcall wrapper will register
the cleanup function in the global cleanup stack. If the pcall'd function
exits normally, the cleanup task will be popped and run.
4. The coroutine could have a __gc method that does the cleanup, just
by popping the cleanup tasks and running them.
This way, if the coroutine is suspended and its resources need to be
cleaned up, we either "close" it by running all of its cleanup routines
in reverse order, or we let it be GC'd, in which case the coroutine's
finalizer will do the same.
David