daisy
daisy

Reputation: 23511

Using IO::Async with vectorized STDIN

I have a multi-threaded program, in the main thread it waits for input from STDIN (forever)

use strict;
use warnings;
use feature 'say';

use IO::Async::Timer::Periodic;
use IO::Async::Loop;
use IO::Async::Handle;


my ($rin, $rout) = ('', '');
vec ($rin, fileno(STDIN), 1) = 1;

my $loop = IO::Async::Loop->new;
my $handle = IO::Async::Handle->new(
    handle => $rin,

    on_read_ready  => sub {
        say 'Ready read';
    },
);

$loop->add( $handle );
$loop->run;

Before switching to IO::Async, I use builtin select call on $rin, and that works just fine.

Now the module complains about $rin, the error was Expected that read_handle can ->fileno at wait.pl line 20.

So, what should I pass in? Or is there any other threads implementation that works better?

P.S The builtin perl threads module keeps crashing, I can't use that

Upvotes: 1

Views: 199

Answers (2)

amon
amon

Reputation: 57640

When creating an IO::Async::Handle, the handle argument to the constructor must be an IO object, or something that responds to a fileno method. If you want to use STDIN, you could do something like

my $handle = IO::Async::Handle->new(handle => *STDIN{IO}, on_read_ready => sub { … });

The real question here is what the hell you are trying to do with vec. The vec function is a way to treat a string as a very C-like piece of memory. It has the following signature:

vec $string, $offset, $bits

which treats the contents of $string as an array of elements with size $bits, of which you are accessing the $offset-th entry. As STDIN has the fileno zero, you will be setting the first bit in that string $rin to one. A simpler way to phrase this is to use pack:

$rin = pack "b", 1;

which incidentally is the same as $rin = chr 1 or $rin = "\x01". Such a string is not useful as an object, a number, or as a filehandle.

Upvotes: 2

Steffen Ullrich
Steffen Ullrich

Reputation: 123375

The handle should be a file handle and not a vector, e.g. use \*STDIN (and read the documentation which clearly describes this). And IO::Async is the complete opposite to threads, e.g. it is an event driven model with non-blocking I/O (which scales much better, definitly compared to perl threads). There are several others like this, AnyEvent and POE probably being the most popular.

Upvotes: 4

Related Questions