nested alarm signals (fwd)

The Chazman chaz at devastator.extern.ucsd.edu
Thu Jun 15 18:19:53 CDT 2000


~sdpm~
>     Carl> There are a large number of system calls that are unsafe to
>     Carl> make while inside a signal handler.  Any attempt to call
>     Carl> these may result in incorrect, undefined, or otherwise
>     Carl> disastrous behavior.  I was looking for a complete list, but
>     Carl> failed to find one.  However, I'm certain that among them
>     Carl> are: fork, exec, read, and write.
>
>     Carl> That means no spawning other processes, and no file or
>     Carl> terminal I/O while in a signal handler.  Frankly, I'm amazed
>
> This is really bad news for me.  I have a pretty large application
> that's based on forking child processes from an alarm signal handler.
> It's working pretty well except for this issue of generating another
> alarm.

Well, I hesitate to do this, but here's the quick and super-dirty,
sweep-it-all-under-the-rug answer.  Manually unblock SIGALRM in your
handler right before you try to spawn another process.  Hopefully
that will allow the new process to receive new alarm signals.  I'm
guessing that it can't because SIGALRM is blocked while inside the
handler, and processes inherit their parent's blocked signal mask
when spawned.

This is a VERY BAD IDEA because fork(), exec(), and many others are
still not guaranteed to work from inside a signal handler.  And while
you may be getting lucky on one implementation of Unix, it may all
fall to pieces on another.  Even different revisions of the same flavor
of Unix may differ in how they react to unsafe system calls inside
signal handlers.  There are just no guarantees, period.

> Given that my example is able to spawn the new process, I wonder what
> it is about that spawned process that indicates that it can't respond
> to (or set?) its own alarm.  That is, is there some way that one can
> look at the output of 'ps' to see that this spawned process is running
> in some kind of special state (e.g. it's running from a signal
> handler)?

I'm guessing it's blocked.  BSD's and Linux's ps can tell you what the
blocked signal mask of a process is.  SysV-style ps can't.  If you're
running on a Linux box, "ps s".  On BSD, "ps o sigmask".  Interpreting
what gets printed out is left as an exercise for the reader.  :-)

> If one can't fork the child processes in a signal handler, how does
> one write a multi-threaded application?

One typically doesn't do any thread manipulations from inside signal
handlers.  Spawn and terminate threads and processes from mainline code.

> My approach was that I would
> spawn these child processes from the alarm signal handler so that they
> would be started even if the program was waiting for user input from
> STDIN.  Like I said, it seems to be working fairly well.  But I don't
> want to write something that won't work on a slightly different flavor
> of Unix or that might not work when the OS is in some slightly
> different state.

If I got into this situation, I'd start using C instead of Perl.  You're
starting to need the fine-grained control that C forces on you.  Here's
what I'd do in C:

1) Register my SIGALRM handler such that interrupted system calls are
   not restarted.
2) Find all system calls (particularly ones that like to block like read())
   in any part of code that might be running when a SIGALRM comes in,
   usually this means everywhere except things that only happen at
   startup and shutdown of the program.
3) Check all such system calls for failure, and in particular, failure
   with the EINTR error code.
4) When one fails with EINTR, check global variable flags that have
   presumably been set by the signal handler, and take whatever out-of-band
   action you had been taking in your old signal handler.  After the
   out-of-band action (spawning off a new processs maybe) is complete,
   reissue the system call that got interrupted.

I don't know how to do this in Perl.  I'm not even sure it's possible to
do in Perl (though it may be -- I'm not Perl guru enough to say either
way).  But the "right" (TM) way to do it, is take the steps I've outlined
above, and have your actual signal handler functions just set global
variable flags for the mainline code to interpret.

> How is the idle callback handled in pTk?  Wouldn't that be some kind
> of alarm?  If so, do the same restrictions apply?

I'm not familiar with pTk; I couldn't say.


                        Carl N Miller
                        chaz at devastator.extern.ucsd.edu
~sdpm~

The posting address is: san-diego-pm-list at hfb.pm.org

List requests should be sent to: majordomo at hfb.pm.org

If you ever want to remove yourself from this mailing list,
you can send mail to <majordomo at happyfunball.pm.org> with the following
command in the body of your email message:

    unsubscribe san-diego-pm-list

If you ever need to get in contact with the owner of the list,
(if you have trouble unsubscribing, or have questions about the
list itself) send email to <owner-san-diego-pm-list at happyfunball.pm.org> .
This is the general rule for most mailing lists when you need
to contact a human.




More information about the San-Diego-pm mailing list