lua-users home
lua-l archive

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

On 14 Jul 2006, at 04:56, Guido Sohne wrote:
I'm trying to write a ping routine inside C code that is hosted in a
lua interpreter. I want to make sure the network works before
embarking on a client/server transaction.

I've decided to craft and send ICMP packets to two hosts (one in the
provider network, the other is the server) to check for reachability.
I also check for signal strength (going out over GPRS, which can
disappear from underneath us) to be sure.

1) I can't call gethostbyname or connect unless I want to 'hang' due
to a timeout.

2) I can set an alarm signal but I can't set a flag in the signal
handler and just return because I'm returning back to the timeout

3) My application is built as a state machine, so there's no event
loop. Instead, each state decides what the next action should be, and
I use (unavoidably) keyboard polling within each state. So we can't
use the event loop as a coroutine unless we are waiting for user input
... so we won't know if we are connected or not until the user tries
to do something?

So can we try doing a setjmp() before we try to connect, and then do a
longjmp from the signal handler. Somehow, that doesn't feel very safe.
If I build intermediate C functions between my connect call and where
we enter from Lua, does that mean setjmp/longjmp will (hopefully!)
only use or touch stack that Lua doesn't care about? Or will it just
work if we longjmp right back into the C function we were called from
in Lua?

Generally it's unsafe to longjmp out of a signal handler. Pretty much the only thing you can do in a signal handler portably and safely is to set a variable of type sig_atomic_t and return. Of course, your platform may provide more guarantees (I doubt it).

What's your C platform?

Your problem is general and thorny. In the ideal world everything that might block (network, files, locks, threads, user input, alarms, etc) should be select(2)able, but sometimes you just can't get at the underlying fd.

You may be able to make your select non-blocking before trying connect.