File Coverage

blib/lib/IO/Async/Loop/EV.pm
Criterion Covered Total %
statement 136 138 98.5
branch 24 32 75.0
condition 3 6 50.0
subroutine 27 27 100.0
pod 12 12 100.0
total 202 215 93.9


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-2026 -- leonerd@leonerd.org.uk
5              
6             package IO::Async::Loop::EV 0.04;
7              
8 17     17   5508902 use v5.20;
  17         89  
9 17     17   76 use warnings;
  17         30  
  17         929  
10              
11 17     17   72 use feature qw( signatures );
  17         25  
  17         2534  
12 17     17   70 no warnings qw( experimental::signatures );
  17         23  
  17         551  
13              
14 17     17   52 use constant API_VERSION => '0.76';
  17         27  
  17         1060  
15              
16 17     17   91 use base qw( IO::Async::Loop );
  17         28  
  17         13356  
17             IO::Async::Loop->VERSION( '0.49' );
18              
19             BEGIN {
20 17 50   17   294275 if( $^V ge v5.36 ) {
21 17         222 builtin->import(qw( refaddr weaken ));
22 17 50       481 warnings->unimport(qw( experimental::builtin )) if $^V lt v5.40;
23             }
24             else {
25 0         0 require Scalar::Util;
26 0         0 Scalar::Util->import(qw( refaddr weaken ));
27             }
28             }
29              
30 17     17   128 use IO::Async::Metrics '$METRICS';
  17         25  
  17         75  
31              
32 17     17   587 use constant _CAN_SUBSECOND_ACCURATELY => 0;
  17         34  
  17         829  
33              
34 17     17   69 use Carp;
  17         21  
  17         835  
35              
36 17     17   7421 use EV;
  17         105390  
  17         19176  
37              
38             =head1 NAME
39              
40             C - use C with C
41              
42             =head1 SYNOPSIS
43              
44             =for highlighter language=perl
45              
46             use IO::Async::Loop::EV;
47              
48             my $loop = IO::Async::Loop::EV->new();
49              
50             $loop->add( ... );
51              
52             $loop->add( IO::Async::Signal->new(
53             name => 'HUP',
54             on_receipt => sub { ... },
55             ) );
56              
57             $loop->run;
58              
59             =head1 DESCRIPTION
60              
61             This subclass of L uses L to perform its work.
62              
63             =cut
64              
65 16         28 sub new ( $class, @args )
66 16     16 1 749532 {
  16         21  
  16         19  
67 16         113 my $self = $class->SUPER::__new( @args );
68              
69 16         8262 $self->{$_} = {} for qw( watch_r watch_w watch_time watch_signal watch_idle watch_process );
70              
71             # Check it's actually active
72 16 100 33     85 if( defined $METRICS and $METRICS->adapter and $METRICS ) {
      66        
73 12         230 weaken( my $weakself = $self );
74 12     80   117 $self->{watch_prepare} = EV::prepare sub (@) { $weakself->pre_wait };
  80         817  
  80         126  
  80         139  
75 12     80   61 $self->{watch_check} = EV::check sub (@) { $weakself->post_wait };
  80         580  
  80         15471568  
  80         128  
76             }
77              
78 16         158 return $self;
79             }
80              
81 87         187 sub loop_once ( $self, $timeout = undef )
82 87     87 1 18282 {
  87         248  
  87         174  
83 87         169 my $timeout_w;
84 87 100       491 if( defined $timeout ) {
85 74         733 $timeout_w = EV::timer $timeout, 0, sub (@) {}; # simply to wake up RUN_ONCE
86             }
87              
88 87         1213185 EV::run( EV::RUN_ONCE );
89             }
90              
91 15         25 sub watch_io ( $self, %params )
92 15     15 1 26560 {
  15         37  
  15         32  
93 15 50       41 my $handle = $params{handle} or die "Need a handle";
94              
95 15 100       40 if( my $on_read_ready = $params{on_read_ready} ) {
96 10         82 $self->{watch_r}{refaddr $handle} = EV::io( $handle, EV::READ, $on_read_ready );
97             }
98              
99 15 100       45 if( my $on_write_ready = $params{on_write_ready} ) {
100 7         42 $self->{watch_w}{refaddr $handle} = EV::io( $handle, EV::WRITE, $on_write_ready );
101             }
102             }
103              
104 11         19 sub unwatch_io ( $self, %params )
105 11     11 1 3940 {
  11         32  
  11         11  
106 11 50       32 my $handle = $params{handle} or die "Need a handle";
107              
108 11 100       26 if( $params{on_read_ready} ) {
109 8         58 delete $self->{watch_r}{refaddr $handle};
110             }
111              
112 11 100       141 if( $params{on_write_ready} ) {
113 7         123 delete $self->{watch_w}{refaddr $handle};
114             }
115             }
116              
117 28         126 sub watch_time ( $self, %params )
118 28     28 1 37155 {
  28         492  
  28         138  
119 28 50       219 my $code = $params{code} or croak "Expected 'code' as CODE ref";
120              
121 28         132 my $w;
122 28 100       218 if( defined $params{after} ) {
123 27         582 $w = EV::timer $params{after}, 0, $code;
124             }
125             else {
126 1         45 $w = EV::periodic $params{at}, 0, 0, $code;
127             }
128              
129 28         347 return $self->{watch_time}{$w} = $w;
130             }
131              
132 17         107 sub unwatch_time ( $self, $id )
133 17     17 1 658 {
  17         22  
  17         19  
134 17         144 delete $self->{watch_time}{$id};
135             }
136              
137 5         29 sub watch_signal ( $self, $signal, $code )
  5         8  
138 5     5 1 4904 {
  5         6  
  5         7  
139 5 100       41 defined $self->signame2num( $signal ) or croak "No such signal '$signal'";
140              
141 4         713 $self->{watch_signal}{$signal} = EV::signal $signal, $code;
142             }
143              
144 2         3 sub unwatch_signal ( $self, $signal )
145 2     2 1 1388 {
  2         2  
  2         3  
146 2         20 delete $self->{watch_signal}{$signal};
147             }
148              
149 6         26 sub watch_idle ( $self, %params )
150 6     6 1 6364 {
  6         21  
  6         9  
151 6 50       23 my $when = delete $params{when} or croak "Expected 'when'";
152              
153 6 50       18 my $code = delete $params{code} or croak "Expected 'code' as a CODE ref";
154              
155 6 50       14 $when eq "later" or croak "Expected 'when' to be 'later'";
156              
157 6         9 my $key;
158             my $w = EV::idle sub {
159 5     5   62 delete $self->{watch_idle}{$key};
160 5         19 goto &$code;
161 6         38 };
162              
163 6         22 $key = "$w";
164 6         18 $self->{watch_idle}{$key} = $w;
165 6         31 return $key;
166             }
167              
168 1         2 sub unwatch_idle ( $self, $id )
169 1     1 1 6 {
  1         2  
  1         2  
170 1         9 delete $self->{watch_idle}{$id};
171             }
172              
173 17         210 sub watch_process ( $self, $pid, $code )
  17         174  
174 17     17 1 56265 {
  17         221  
  17         182  
175 19     19   3272 $self->{watch_process}{$pid} = EV::child $pid, 0, sub ( $w, @ ) {
  19         53  
  19         27  
176 19         261 $code->( $w->rpid, $w->rstatus );
177 17         1425 };
178             }
179              
180 1         5 sub unwatch_process ( $self, $pid )
181 1     1 1 143 {
  1         4  
  1         4  
182 1         8 delete $self->{watch_process}{$pid};
183             }
184              
185             =head1 AUTHOR
186              
187             Paul Evans
188              
189             =cut
190              
191             0x55AA;