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"); }

In reply to timeouts and errors with IO::Select:: and CORE:: select (was Re: Msg.pm extended with "workproc". IO::Select docs) by ikegami
in thread Msg.pm extended with "workproc". IO::Select docs by Wiggins

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.