File Coverage

blib/lib/IO/Async/Loop/EV.pm
Criterion Covered Total %
statement 98 98 100.0
branch 22 28 78.5
condition 3 6 50.0
subroutine 26 26 100.0
pod 12 12 100.0
total 161 170 94.7


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, 2012-2020 -- leonerd@leonerd.org.uk
5              
6             package IO::Async::Loop::EV;
7              
8 17     17   267116 use strict;
  17         61  
  17         419  
9 17     17   71 use warnings;
  17         25  
  17         656  
10              
11             our $VERSION = '0.03';
12 17     17   86 use constant API_VERSION => '0.76';
  17         25  
  17         1182  
13              
14 17     17   87 use base qw( IO::Async::Loop );
  17         26  
  17         11484  
15             IO::Async::Loop->VERSION( '0.49' );
16              
17 17     17   307363 use Scalar::Util qw( weaken );
  17         34  
  17         856  
18              
19 17     17   91 use IO::Async::Metrics '$METRICS';
  17         39  
  17         69  
20              
21 17     17   600 use constant _CAN_SUBSECOND_ACCURATELY => 0;
  17         33  
  17         807  
22              
23 17     17   85 use Carp;
  17         24  
  17         767  
24              
25 17     17   6743 use EV;
  17         25018  
  17         14152  
26              
27             =head1 NAME
28              
29             C - use C with C
30              
31             =head1 SYNOPSIS
32              
33             use IO::Async::Loop::EV;
34              
35             my $loop = IO::Async::Loop::EV->new();
36              
37             $loop->add( ... );
38              
39             $loop->add( IO::Async::Signal->new(
40             name => 'HUP',
41             on_receipt => sub { ... },
42             ) );
43              
44             $loop->run;
45              
46             =head1 DESCRIPTION
47              
48             This subclass of L uses L to perform its work.
49              
50             =cut
51              
52             sub new
53             {
54 16     16 1 427 my $class = shift;
55 16         118 my $self = $class->SUPER::__new( @_ );
56              
57 16         769 $self->{$_} = {} for qw( watch_r watch_w watch_time watch_signal watch_idle watch_process );
58              
59             # Check it's actually active
60 16 100 33     119 if( defined $METRICS and $METRICS->adapter and $METRICS ) {
      66        
61 12         2970 weaken( my $weakself = $self );
62 12     77   81 $self->{watch_prepare} = EV::prepare sub { $weakself->pre_wait };
  77         525  
63 12     77   59 $self->{watch_check} = EV::check sub { $weakself->post_wait };
  77         19286307  
64             }
65              
66 16         3410 return $self;
67             }
68              
69             sub loop_once
70             {
71 84     84 1 29111 my $self = shift;
72 84         194 my ( $timeout ) = @_;
73              
74 84         126 my $timeout_w;
75 84 100       313 if( defined $timeout ) {
76 71     13   608 $timeout_w = EV::timer $timeout, 0, sub {}; # simply to wake up RUN_ONCE
77             }
78              
79 84         856744 EV::run( EV::RUN_ONCE );
80             }
81              
82             sub watch_io
83             {
84 10     10 1 19848 my $self = shift;
85 10         35 my %params = @_;
86              
87 10 50       55 my $handle = $params{handle} or die "Need a handle";
88              
89 10 100       28 if( my $on_read_ready = $params{on_read_ready} ) {
90 7         50 $self->{watch_r}{$handle} = EV::io( $handle, EV::READ, $on_read_ready );
91             }
92              
93 10 100       32 if( my $on_write_ready = $params{on_write_ready} ) {
94 5         29 $self->{watch_w}{$handle} = EV::io( $handle, EV::WRITE, $on_write_ready );
95             }
96             }
97              
98             sub unwatch_io
99             {
100 9     9 1 4923 my $self = shift;
101 9         32 my %params = @_;
102              
103 9 50       25 my $handle = $params{handle} or die "Need a handle";
104              
105 9 100       21 if( $params{on_read_ready} ) {
106 6         46 delete $self->{watch_r}{$handle};
107             }
108              
109 9 100       86 if( $params{on_write_ready} ) {
110 5         60 delete $self->{watch_w}{$handle};
111             }
112             }
113              
114             sub watch_time
115             {
116 31     31 1 36993 my $self = shift;
117 31         298 my %params = @_;
118              
119 31 50       208 my $code = $params{code} or croak "Expected 'code' as CODE ref";
120              
121 31         75 my $w;
122 31 100       116 if( defined $params{after} ) {
123 30         287 $w = EV::timer $params{after}, 0, $code;
124             }
125             else {
126 1         7 $w = EV::periodic $params{at}, 0, 0, $code;
127             }
128              
129 31         266 return $self->{watch_time}{$w} = $w;
130             }
131              
132             sub unwatch_time
133             {
134 19     19 1 842 my $self = shift;
135 19         47 my ( $id ) = @_;
136              
137 19         167 delete $self->{watch_time}{$id};
138             }
139              
140             sub watch_signal
141             {
142 5     5 1 3005 my $self = shift;
143 5         11 my ( $signal, $code ) = @_;
144              
145 5 100       45 defined $self->signame2num( $signal ) or croak "No such signal '$signal'";
146              
147 4         545 $self->{watch_signal}{$signal} = EV::signal $signal, $code;
148             }
149              
150             sub unwatch_signal
151             {
152 2     2 1 2392 my $self = shift;
153 2         17 my ( $signal ) = @_;
154              
155 2         92 delete $self->{watch_signal}{$signal};
156             }
157              
158             sub watch_idle
159             {
160 6     6 1 8795 my $self = shift;
161 6         19 my %params = @_;
162              
163 6 50       58 my $when = delete $params{when} or croak "Expected 'when'";
164              
165 6 50       15 my $code = delete $params{code} or croak "Expected 'code' as a CODE ref";
166              
167 6 50       13 $when eq "later" or croak "Expected 'when' to be 'later'";
168              
169 6         9 my $key;
170             my $w = EV::idle sub {
171 5     5   63 delete $self->{watch_idle}{$key};
172 5         15 goto &$code;
173 6         30 };
174              
175 6         18 $key = "$w";
176 6         14 $self->{watch_idle}{$key} = $w;
177 6         23 return $key;
178             }
179              
180             sub unwatch_idle
181             {
182 1     1 1 4 my $self = shift;
183 1         2 my ( $id ) = @_;
184              
185 1         7 delete $self->{watch_idle}{$id};
186             }
187              
188             sub watch_process
189             {
190 17     17 1 41276 my $self = shift;
191 17         159 my ( $pid, $code ) = @_;
192              
193             $self->{watch_process}{$pid} = EV::child $pid, 0, sub {
194 19     19   2011 my $w = shift;
195 19         127 $code->( $w->rpid, $w->rstatus );
196 17         1100 };
197             }
198              
199             sub unwatch_process
200             {
201 1     1 1 270 my $self = shift;
202 1         3 my ( $pid ) = @_;
203              
204 1         8 delete $self->{watch_process}{$pid};
205             }
206              
207             =head1 AUTHOR
208              
209             Paul Evans
210              
211             =cut
212              
213             0x55AA;