Uri Guttman wrote:
> are you doing your own signal handling in perl? if so, you should switch
> to event.pm. perl's signal handling is well known to be unsafe.
I'm putting together some code samples to explain how event loops work,
but for any serious even-driven work, I'd use one of the available
libraries. FWIW, the slides will be on my web site some time tomorrow.
> the way to handle that properly is to check for any pending signals
> before you enter the select call (while blocking any from coming in) and
> then checking after the select returns. this can only be done correctly
> in C.
There's no way in perl or C that I know of to atomically set a signal
mask and enter a select call. I've seen rumors of a pselect library
call available on some systems that can do this. A sigprocmask call
followed by a select call has a race condition, because a signal can
come in between the two statements. How do you solve this in C? I've
seen a klugey solution that requires a setjmp/longjmp.
If you don't have to watch for I/O, and you're only looking for signals,
then a sigsuspend is a nice solution. Here's a code fragment that does
this below, using the POSIX module. I love using the POSIX module to do
things in perl that people think can only be done in C. It might should
be doing a sigaction rather that using the SIG hash, now that I've
re-read a few more of the FAQs.
This solution would work with I/O if you can get a SIGIO when there's
I/O to check, but it looks like that's only available for certain types
of I/O.
----snip
#!/usr/bin/perl -w
use strict;
use POSIX qw(SIGINT SIGALRM SIG_SETMASK sigprocmask sigsuspend);
my $empty_mask = new POSIX::SigSet;
my $block_mask = new POSIX::SigSet (SIGINT, SIGALRM);
sigprocmask(SIG_SETMASK, $block_mask);
$SIG{CHLD} = \&sigchld_handler;
$SIG{ALRM} = \&sigalrm_handler;
# additional setup here
while (1) {
sigsuspend($empty_mask);
# signals are blocked again
# process events now
}
----snip
--
Danny Faught
Tejas Software Consulting
http://www.tejasconsulting.com