Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

IO::Select and alarm()

by Maddingue (Sexton)
on Mar 19, 2009 at 14:40 UTC ( [id://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)?

Replies are listed 'Best First'.
Re: IO::Select and alarm()
by ikegami (Patriarch) 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
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-03-19 09:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found