lua-users home
lua-l archive

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

"Sam Roberts" <> writes:
> On Tue, Dec 2, 2008 at 5:02 PM,  <> wrote:
> >> On Tuesday 02, wrote:
> >>> 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?
> Just do it. Resume, and throw an error immediately.
> If your yields always exect to get back
>   true, arg1, arg2
> or
>   nil, emsg

Yes, this is sort of what I do now. That is the C callbacks only throw
an error on bad arguments. All other kinds of errors are of the
return nil, errormsg type (possibly after a yield).

I guess you could argue that all errors that can happen while a thread
is yielded are exactly io errors and hence should be handled like that.
In fact right now I'm struggling to find a good example where throwing
an error after a yield is a good idea, but I'm sure one exists.

One example is if the thread has a very specific purpose to run which is
completely destroyed by the error. Like if an incoming connection is
closed you might want to just throw an error on the handling thread and
be done with it.

> whenever the yield returns, it can assert success:
> ok, arg1, arg2 = assert(coroutine.yield("read-wait", {fd=4}))

Well, the whole point of my program is to have away with explicit yields
or mucking about with file descripters from the Lua side, so it would be
more like

local function conn_handler(conn)
	line = assert(conn:receive('*l'))

server = tcp.listen('*', 5000, conn_handler)

..where conn:send() and conn:receive() are C callbacks that yield if
they can't complete immediately so that more conn_handler()s can run
simultaneusly without the writer of the Lua script having to worry about
all this.

Come to think of it this probably isn't a very good example of a place
where you'd want to throw an error on the yielded thread since the
explicit assert()s give you the chance to do something like

	connection_count = connection_count - 1

before the thread ends.

> Sam

Thank you

Another option is to have some Lua code wrap all the C callbacks that
might yield in an assert()-like function (or assert() itself) that
calls errors on some magic input, before any script is run. This
just seems like a very inefficent and awkward solution to me.

If only lua_error() did behave as Robert suggested, or even better
if there were a primitive like lua_cancel() to cancel execution
on a running (yielded) thread..