in reply to Msg.pm extended with "workproc". IO::Select docs
Test based on documentation:
use strict; use warnings; use IO::Select qw( ); use IO::Socket qw( ); my $lsn = IO::Socket::INET->new(Listen => 1, LocalPort => 8080); my $sel = IO::Select->new( $lsn ); my $no_error = my ($r_ready, $w_ready, $e_ready) = IO::Select->select($sel, undef, undef, 2.2); if ($no_error) { print("No error\n"); print("Num readers ready: ", 0+@$r_ready, "\n"); print("Num writers ready: ", 0+@$w_ready, "\n"); print("Num errors ready: ", 0+@$e_ready, "\n"); } else { print("Error ", 0+$!, ": $!\n"); }
Win>perl a.pl Error 0: linux$ perl a.pl Error 29: Illegal seek
Timeout returns as an error, but with a useless error message. There's no way to differentiate between errors and timeouts, and $! is only valid for errors.
What about select? It could possibly return undef on error and 0 on timeout.
Turns out it returns -1 on error.
use strict; use warnings; use IO::Socket qw( ); my $lsn = IO::Socket::INET->new(Listen => 1, LocalPort => 8080); my $r_in = my $w_in = my $e_in = ''; vec($r_in, fileno($lsn), 1) = 1; vec($r_in, 100, 1) = 1 if $ARGV[0]; my $nfound = select( my $r_ready = $r_in, my $w_ready = $w_in, my $e_ready = $e_in, 2.2, ); $nfound >= 0 or die("select: (" . (0+$^E) . ") $^E\n"); if ($nfound) { print("nfound = $nfound\n"); } else { print("Timeout\n"); }
Win>perl a.pl 0 Timeout Win>perl a.pl 1 select: (10038) Unknown error Using $^E instead of $! gives select: (10038) An operation was attempted on something that is not a socket linux$ perl a.pl 0 Timeout linux$ perl a.pl 1 select: (9) Bad file descriptor
So the documentation for select needs to mention it returns -1 on error and that a timeout is not an error.
And the following line needs to be changed in IO::Select's select:
- if(select($rb,$wb,$eb,$t) > 0) + if(select($rb,$wb,$eb,$t) >= 0)
(Well, you could come up with a more efficient implementation.)
With the fix to IO::Select, the usage would be:
use strict; use warnings; use IO::Select qw( ); use IO::Socket qw( ); my $lsn = IO::Socket::INET->new(Listen => 1, LocalPort => 8080); my $sel = IO::Select->new( $lsn ); my ($r_ready, $w_ready, $e_ready) = IO::Select->select($sel, undef, undef, 2.2) or die("Can't select: (" . (0+$!) . ") $!\n"); if (@$r_ready + @$w_ready + @$e_ready == 0) { print("Timeout\n"); } else { print("Num readers ready: ", 0+@$r_ready, "\n"); print("Num writers ready: ", 0+@$w_ready, "\n"); print("Num errors ready: ", 0+@$e_ready, "\n"); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: timeouts and errors with IO::Select:: and CORE:: select (was Re: Msg.pm extended with "workproc". IO::Select docs)
by Wiggins (Hermit) on Oct 12, 2009 at 13:15 UTC | |
by ikegami (Patriarch) on Oct 12, 2009 at 17:13 UTC |