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

[Win32] IO::Select's can_read method

by syphilis (Chancellor)
on Dec 09, 2011 at 09:16 UTC ( #942603=perlquestion: print w/replies, xml ) Need Help??
syphilis has asked for the wisdom of the Perl Monks concerning the following question:

Hi, In a nutshell, the IO::Select can_read method doesn't work on MS Windows, afaict.

The demo:
use warnings; use strict; use IO::Select; open(RD, '<', $0) or die "Can't open RD: $!"; my $s = IO::Select->new(); $s->add(\*RD); my @r = $s->can_read(); my $cum; if(@r) { # Assign the first 7 lines of this # file to $cum (1 byte at a time), # and print out $cum do { my $byte; sysread $r[0], $byte, 1; $cum .= $byte; } until $cum =~ /new\(\);/; print "\n\$cum:\n\n$cum\n"; } else { print "\@r contains no elements\n"; }
On Cygwin and Linux, as expected, that prints out the first 7 lines of itself (ie the first 7 lines of $0).

But on Windows, it just prints out "@r contains no elements".
This happens because can_read() fails to return anything on Windows - and that's irrespective of the timeout value supplied as an argument to can_read (or even if *no* argument is supplied).

So ... I'm wondering how (on Windows) do we query an IO::Select object in such a way that it returns the same as can_read does on Cygwin/Linux ?


Replies are listed 'Best First'.
Re: [Win32] IO::Select's can_read method
by Corion (Pope) on Dec 09, 2011 at 09:27 UTC

    select (and IO::Select) only work on Sockets, not on pipes or filehandles on Windows.

    As far as I have seen, it is not easy to conveniently retrofit select onto Windows filehandles, because asynchronous Windows IO seems mostly to be done using IO Completion Ports. These allow you to asynchronously read in data, but they don't allow you to check whether there actually is data available to be read. The same problem occurs when using threads.

      select (and IO::Select) only work on Sockets, not on pipes or filehandles on Windows

      Which reminds me that, while the demo portrays the problem using a filehandle, in the real-world app we're dealing with pipes. (To that extent, it was a bad demo).

      For filehandles perhaps we can query the list returned by the IO::Select handles method to see if they're readable (using Win32::Fmode or Filehandle::Fmode) ... would that emulate the work of the can_read method (if it's even feasible) ?

      But then, like I've just said, in actuality they're *pipes* not filehandles ...


        Unix select behaviour for pipes could be emulated on Win32 using PeekNamedPipe().

        Although the function name suggests that this is design for use with named pipes, it also works with anonymous pipes:

        hNamedPipe in

        A handle to the pipe. This parameter can be a handle to a named pipe instance, as returned by the CreateNamedPipe or CreateFile function, or it can be a handle to the read end of an anonymous pipe, as returned by the CreatePipe function. The handle must have GENERIC_READ access to the pipe.

        Similarly, can_read() could be implemented for files using Alertable IO, and callbacks placed on the Asynchronous Procedure Queue.

        Implementing either would require a substantial rewrite of win32_select() in win32sck.c

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The start of some sanity?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://942603]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (5)
As of 2018-03-19 22:58 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (246 votes). Check out past polls.