Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

IO::Select and alarm()

by Maddingue (Sexton)
on Mar 19, 2009 at 14:40 UTC ( #751738=perlquestion: print w/ replies, xml ) Need Help??
Maddingue has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks, I am writing a program built around a loop on a IO::Select object. So far so good. Now I need to throw in a task that must be regularly executed. So I thought setting it as a SIGALRM handler. Sounds simple:
use strict; use warnings; use IO::Select; use IO::Socket; use POSIX qw< :signal_h >; my $port = 6681; my $listen = IO::Socket::INET->new( Proto => "tcp", LocalPort => $port, Listen => 10, Timeout => 10, ) or die "Can't bind socket to port $port: $!"; my $select = IO::Select->new($listen); print STDERR "listing on port $port\n"; my $alarm_handler = sub { print STDERR "! alarm handler\n"; alarm(2); }; my $sigset = POSIX::SigSet->new(SIGALRM); my $sa_alarm = POSIX::SigAction->new($alarm_handler, $sigset, SA_RESTA +RT); sigaction(SIGALRM, $sa_alarm); #$SIG{ALRM} = $alarm_handler; alarm(2); while (my @ready = $select->can_read) { for my $fh (@ready) { if ($fh == $listen) { my $sock = $listen->accept; $select->add($sock); } else { # ... } } }
Execpt that when running this program, it outputs:
$ perl sigalarm.pl listing on port 6681 ! alarm handler
and exits after the first SIGALRM. What is the obvious thing I'm missing to make the while restart (apart from nesting it in a while(1) { .. } loop)?

Comment on IO::Select and alarm()
Select or Download Code
Replies are listed 'Best First'.
Re: IO::Select and alarm()
by ikegami (Pope) on Mar 19, 2009 at 14:48 UTC
    use Errno qw( EINTR ); for (;;) { my @ready = $select->can_read() or do { next if $! == EINTR; last; }; for my $fh (@ready) { ... } }

    Untested.

    Note that die("select: $!\n"); would be more appropriate than last, but I preserved the behaviour of the OP.

      Thank you, it works.

      Now I feel stupid because I should have remembered this :)

        There's a difference between can_read and select. can_read returns immediately when the object has no file handles, but I assumed it sleeps indefinitely like select in that situation.

        That means there's a bug in my earlier version. The OP's code is equivalent to

        use Errno qw( EINTR ); while ($select->count()) { my @ready = $select->can_read() or do { next if $! == EINTR; last; # Should be die("select: $!\n"); }; for my $fh (@ready) { ... } }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://751738]
Approved by moritz
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (17)
As of 2015-07-28 18:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (258 votes), past polls