2

I'm using IO::Select.

It is an OOP wrapper for the normal select call, but it exposes can_read() and can_write() methods. Is there no way to block waiting for a read or write socket? Does this not (almost) defeat the purpose of having IO::Select in the first place?

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
MK.
  • 33,605
  • 18
  • 74
  • 111
  • Do we really need a [tag:wtf] tag? – Benjamin W. Feb 10 '17 at 04:34
  • 2
    @BenjaminW. I've been trying to add it for years. – MK. Feb 10 '17 at 04:41
  • @MK. , although you can probably use the static `select` call for this (which, for some reason, ignores the existing object model), I would recommend that you consider `select` as broken for any real network use... if your application opens more than 1023 file descriptors, the `select` system call will crash on some systems. – Myst Feb 10 '17 at 05:15
  • The fact that select has limitations is not an excuse for making the object model even more broken. – MK. Feb 10 '17 at 05:23
  • 3
    Uhh, [IO::Select->select](http://perldoc.perl.org/IO/Select.html#select-%28-READ%2c-WRITE%2c-EXCEPTION-[%2c-TIMEOUT-]-%29)? – ThisSuitIsBlackNot Feb 10 '17 at 05:31
  • @MK. [Here](http://stackoverflow.com/a/40192400/2173773) is an example where I use select with both read and write – Håkon Hægland Feb 10 '17 at 09:36

2 Answers2

3

Use IO::Select->select:

select ( READ, WRITE, EXCEPTION [, TIMEOUT ] )

select is a static method, that is you call it with the package name like new. READ, WRITE and EXCEPTION are either undef or IO::Select objects. TIMEOUT is optional and has the same effect as for the core select call.

The result will be an array of 3 elements, each a reference to an array which will hold the handles that are ready for reading, writing and have exceptions respectively. Upon error an empty list is returned.

For example:

my $rsel  = IO::Select->new($rfh);
my $wsel  = IO::Select->new($wfh);
my $esel  = IO::Select->new($rfh, $wfh);

my @ready = IO::Select->select($rsel, $wsel, $esel, undef);
Community
  • 1
  • 1
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
2

If TIMEOUT is not given and any handles are registered then the call will block.

It looks like can_read and can_write will block if you don't pass a timeout. I'd suggest that this is rarely what is desired, though it might be under some circumstances.

Personally, I'd suggest using one of the many event modules (POE, AnyEvent, etc) instead. It's a bit more to get going, but handles more scenarios more cleanly.

Tanktalus
  • 21,664
  • 5
  • 41
  • 68
  • Right, so i want it to block, but I want to to block until any socket becomes available, either for read or for write. And it doesn't appear to be possible with this API, which to me makes it look completely broken and question sanity of library authors – MK. Feb 10 '17 at 04:52
  • @MK Correction on my previous comment -- `can_read` works with _all_ sockets "registered" with the object (which is done using `add`). So it does exactly what you ask? – zdim Feb 10 '17 at 07:22
  • no, i want to be able to wait for both read and write at the same time. I suppose select is exposed there so my fury was misdirected. – MK. Feb 10 '17 at 07:31
  • @MK. Can you combine them in the `while` loop condition, in a _non-blocking_ mode? Like `while ( @read = $sel->can_read(timeout) or @write = $sel->can_write(timeout) )` ? – zdim Feb 10 '17 at 07:41
  • @zdim that defeats the purpose of select, the ability to block waiting for any event. – MK. Feb 10 '17 at 07:49
  • @MK. Sure, no need to poll if you don't mind the static `select`. Then I misunderstood the question (it starts out by quoting docs but ignores the static `select` on that short page, and the comments pointing it out). Sorry for the noise then. Remove these comments? – zdim Feb 10 '17 at 08:18