lua-users home
lua-l archive

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

I hope someone has dealt with this issue before and can offer advice.
Sorry if this message rambles; I guess I'm thinking out loud.  (I'm using
Lua 4.0 alpha here.)

We've implemented a command-line interpreter in Lua for our product.  Some
of the commands the user may execute may either take a very long time or
potentially never return.  These commands are usually written as C code
(typically operating system services).  To deal with this, we want to
support the user hitting control-C on the console.  This should break the
currently running command, and either return to or restart the command
interpreter.  (Return is nicer, but restarting is going to be easier.)

Doesn't sound too bad, does it?  I initially thought this would be easy--
I'll do a setjmp() prior to entering the command-line interpreter, and use
it as a return point if a control-C comes along.  But then I started to
think more about it, and I started to get worried.

One issue with this is that the control-C can come along at *any* time.
Consider what happens if we're executing Lua code that is building a table.
The opcode in the virtual machine is OP_CREATETABLE, and this could be
interrupted *anywhere* between the start and end of the execution of this
opcode.  So what happens if (for example) the allocation of the table is a
success, but before Lua has a chance to put the allocation in its list of
objects, control-C comes along and Lua doesn't get a chance to finish?

If you're under some flavor of Unix or Windows or any other modern
operating system, you probably don't care.  You think, "well, the operating
system will clean it up for me."  That's not the case for some operating
systems.  We use VxWorks, which does virtually nothing for you.  Every
memory allocation, file descriptor, socket, etc. that you might allocate
during the course of your program is the program's responsibility to clean
up-- even if the operating system originally gave it to you!  Yes, this is
icky.  This gives you control, but also increases your responsibility.

One way to deal with this horror is to not allow control-C during those
times when it is dangerous-- and dangerous is defined as being "any time
Lua code is running."  One might treat the Lua virtual machine as a
critical section, disabling control-C interruptions during the execution of
opcodes.  But that's probably not enough.  Take the case of OP_CREATETABLE.
The same function that creates tables as an opcode is also available for
use by C code.  I could be creating tables as part of C code outside the
context of the Lua virtual machine's OP_CREATETABLE opcode.  So without a
laborious analysis of ever single function in Lua, it is safest to treat it
all as potentially dangerous to interrupt.

So this means that long-running commands that one might want to interrupt
with control-C would selectively enable the control-C interrupt only when
it was known to be safe.  That's not that bad in our case-- we only have a
few such commands.  It's more responsibility for the programmer, but hey,
we've get to worry about a lot of other things that are more scary anyway.

So that's pretty much it.  Anyone have any ideas?  Just for the record, I
don't see any of this as a defect in Lua.  The Lua authors can't possibly
think about every quirky platform that Lua runs on-- we who implement Lua
on weird platforms have to be the ones who deal with these kinds of issues.