Problem with signals & exceptions...

Donn Cave donn at u.washington.edu
Thu Jul 29 00:43:27 EDT 1999


Eric Lee Green <eric at estinc.com> writes:

| Donn Cave wrote:
|> 
|> Eric Lee Green <e_l_green at hotmail.com> writes:
|>| I'm having trouble catching my thrown exceptions under FreeBSD 3.2. I am
|>| using the Python 1.5.2 that came with FreeBSD 3.2 (well, on disk 1 of
|>| the <n>-disk set). The following program works properly under Red Hat
|>| Linux version 6.0 running a self-compiled Python 1.5.2 (in place of the
|>| 1.5.1 which comes with Red Hat 6.0, which does not properly handle
|>| signals during socket i/o calls). How it works: it listens to port 6664.
|>| When it gets a connection, it then sets an alarm handler and alarm and
|>| then tries to read from the socket. If it does not get data within 10
|>| seconds, it then times out, at which point the alarm handler throws an
|>| exception and aborts the socket read.
|> 
|> I tried this exception-from-handler notion on Digital UNIX and BeOS,
|> and it does seem to work the way I guess you expect, but I do find it
|> weird. A signal handler executes outside the normal flow of control,
|> so it's not obvious to me where its exceptions ought to surface.
|> Probably it should be expected to work the same way on various platforms
|> for any given version of Python, but would future versions of Python be
|> guaranteed to work this way also?
|
| That, of course, is the ten million dollar question. The operation of signals
| in "C" is extremely well documented and described. Under Python, it's ???. 

Well, it's not capricious, there are some limits to what can reasonably
be done with signals in an interpreter like Python.  In normal use the
main thing to remember is that signal handlers execute in the same thread,
and therefore start on instruction boundaries.  A C signal handler executes
on a machine instruction granularity, a Python signal handler executes on
a Python instruction granularity ... which could be a long time.  It doesn't
look like you've run into this here, though.  As another followup points
out, signal handlers are very limited.  Can you throw a C++ exception from
a handler, and catch it in the interrupted section?  Don't think so.

| I changed my code to set a global variable rather than throw an exception and
| that works the way you'd expect. A socket.error exception is thrown, and I
| catch it, check the global variable, if the global variable is set I print "go
| a timeout!" else re-throw the exception. 

That should be safe.

| In the actual working code I scrapped the alarm signal altogether and instead
| do a select() call with a timeout, which presumably is guaranteed to work the
| same on all platforms (it better, the select call is a POSIX standard!). 

Hm, don't think select() is POSIX 1003.1.  Occasionally it can be found
supported only for socket devices, another Berkeley-ism that POSIX takes
a characteristically dim view of.  But this application should be no problem.

	Donn Cave, University Computing Services, University of Washington
	donn at u.washington.edu




More information about the Python-list mailing list