File Coverage

blib/lib/Future/IO/Impl/IOAsync.pm
Criterion Covered Total %
statement 53 54 98.1
branch 8 8 100.0
condition 9 16 56.2
subroutine 11 12 91.6
pod 0 4 0.0
total 81 94 86.1


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2019-2021 -- leonerd@leonerd.org.uk
5              
6             package Future::IO::Impl::IOAsync;
7              
8 3     3   62028 use strict;
  3         6  
  3         96  
9 3     3   15 use warnings;
  3         6  
  3         84  
10 3     3   18 use base qw( Future::IO::ImplBase );
  3         6  
  3         231  
11              
12             =head1 NAME
13              
14             C - implement C using C
15              
16             =head1 DESCRIPTION
17              
18             This module provides an implementation for L which uses
19             L.
20              
21             There are no additional methods to use in this module; it simply has to be
22             loaded, and will provide the C implementation methods.
23              
24             use Future::IO;
25             use Future::IO::Impl::IOAsync;
26              
27             my $f = Future::IO->sleep(5);
28             ...
29              
30             =cut
31              
32 3     3   15 use IO::Async::Loop;
  3         9  
  3         1566  
33              
34             __PACKAGE__->APPLY;
35              
36             my $loop;
37              
38             sub sleep
39             {
40 21     21 0 9942 shift;
41 21         57 my ( $secs ) = @_;
42              
43 21   66     126 return ( $loop //= IO::Async::Loop->new )->delay_future( after => $secs );
44             }
45              
46             my %watching_read_by_fileno; # {fileno} => [@futures]
47              
48             # Not (yet) part of Future::IO API but it seems a useful way to build this
49             sub ready_for_read
50             {
51 15     15 0 8532 shift;
52 15         42 my ( $fh ) = @_;
53              
54 15   100     69 my $watching = $watching_read_by_fileno{ $fh->fileno } //= [];
55              
56 15   33     207 $loop //= IO::Async::Loop->new;
57 15         66 my $f = $loop->new_future;
58              
59 15         27 my $was = scalar @$watching;
60 15         36 push @$watching, $f;
61              
62 15 100       51 return $f if $was;
63              
64             $loop->watch_io(
65             handle => $fh,
66             on_read_ready => sub {
67 15     15   66 $watching->[0]->done;
68 15         2688 shift @$watching;
69              
70 15 100       63 return if scalar @$watching;
71              
72 12         66 $loop->unwatch_io(
73             handle => $fh,
74             on_read_ready => 1,
75             );
76 12         33 delete $watching_read_by_fileno{ $fh->fileno };
77             },
78 12         114 );
79              
80 12         132 return $f;
81             }
82              
83             my %watching_write_by_fileno; # {fileno} => [@futures]
84              
85             sub ready_for_write
86             {
87 18     18 0 22809 shift;
88 18         42 my ( $fh ) = @_;
89              
90 18   100     54 my $watching = $watching_write_by_fileno{ $fh->fileno } //= [];
91              
92 18   33     234 $loop //= IO::Async::Loop->new;
93 18         60 my $f = $loop->new_future;
94              
95 18         33 my $was = scalar @$watching;
96 18         39 push @$watching, $f;
97              
98 18 100       57 return $f if $was;
99              
100             $loop->watch_io(
101             handle => $fh,
102             on_write_ready => sub {
103 18     18   69 $watching->[0]->done;
104 18         3186 shift @$watching;
105              
106 18 100       63 return if scalar @$watching;
107              
108 15         60 $loop->unwatch_io(
109             handle => $fh,
110             on_write_ready => 1,
111             );
112 15         39 delete $watching_write_by_fileno{ $fh->fileno };
113             },
114 15         111 );
115              
116 15         120 return $f;
117             }
118              
119             sub waitpid
120             {
121 3     3 0 209040 shift;
122 3         39 my ( $pid ) = @_;
123              
124 3   33     170 my $f = ( $loop //= IO::Async::Loop->new )->new_future;
125              
126             $loop->watch_process( $pid, sub {
127 3     3   15 my ( undef, $wstatus ) = @_;
128 3         32 $f->done( $wstatus );
129 3         416 } );
130 3     0   121 $f->on_cancel( sub { $loop->unwatch_process( $pid ) } );
  0         0  
131              
132 3         139 return $f;
133             }
134              
135             =head1 AUTHOR
136              
137             Paul Evans
138              
139             =cut
140              
141             0x55AA;