File Coverage

blib/lib/IO/Async/Loop/Event.pm
Criterion Covered Total %
statement 101 101 100.0
branch 39 48 81.2
condition 7 8 87.5
subroutine 20 20 100.0
pod 12 12 100.0
total 179 189 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::Event;
7              
8 12     12   5263 use strict;
  12         23  
  12         288  
9 12     12   48 use warnings;
  12         22  
  12         456  
10              
11             our $VERSION = '0.03';
12 12     12   51 use constant API_VERSION => '0.76';
  12         24  
  12         740  
13              
14 12     12   59 use base qw( IO::Async::Loop );
  12         16  
  12         7861  
15             IO::Async::Loop->VERSION( '0.49' );
16              
17 12     12   148794 use constant _CAN_SUBSECOND_ACCURATELY => 0;
  12         26  
  12         598  
18              
19 12     12   62 use Carp;
  12         23  
  12         626  
20              
21 12     12   4855 use Event;
  12         96798  
  12         53  
22              
23             =head1 NAME
24              
25             C - use C with C
26              
27             =head1 SYNOPSIS
28              
29             use IO::Async::Loop::Event;
30              
31             my $loop = IO::Async::Loop::Event->new();
32              
33             $loop->add( ... );
34              
35             $loop->run;
36              
37             =head1 DESCRIPTION
38              
39             This subclass of L uses L to perform its work.
40              
41             =cut
42              
43             sub new
44             {
45 11     11 1 132 my $class = shift;
46 11         75 my $self = $class->SUPER::__new( @_ );
47              
48 11         521 $self->{$_} = {} for qw( watch_io watch_sig watch_idle );
49              
50 11         32 return $self;
51             }
52              
53             sub loop_once
54             {
55 57     57 1 20756 my $self = shift;
56 57         121 my ( $timeout ) = @_;
57              
58 57 100       180 if( defined $timeout ) {
59 56         18390667 Event::one_event( $timeout );
60             }
61             else {
62 1         14 Event::one_event;
63             }
64             }
65              
66             sub run
67             {
68 5     5 1 109 my $self = shift;
69              
70 5         22 my $result = Event::loop();
71 5 100       104 wantarray ? @$result : $result->[0];
72             }
73              
74             sub stop
75             {
76 5     5 1 396296 my $self = shift;
77 5         21 my @result = @_;
78              
79 5         68 Event::unloop( \@result );
80             }
81              
82             sub watch_io
83             {
84 9     9 1 20245 my $self = shift;
85 9         33 my %params = @_;
86              
87 9 50       31 my $handle = $params{handle} or die "Need a handle";
88              
89 9   100     52 my $w = $self->{watch_io}{$handle} ||= [];
90              
91 9 100       23 if( my $on_read_ready = $params{on_read_ready} ) {
92 6         15 $w->[1] = $on_read_ready;
93             }
94              
95 9 100       21 if( my $on_write_ready = $params{on_write_ready} ) {
96 5         6 $w->[2] = $on_write_ready;
97             }
98              
99 9 100       30 my $poll = ( $w->[1] ? "r" : "" ) . ( $w->[2] ? "w" : "" );
    100          
100              
101 9 100       32 if( $w->[0] ) {
102 1         8 $w->[0]->poll( $poll );
103             }
104             else {
105             $w->[0] = Event->io(
106             poll => $poll,
107             fd => $handle,
108             cb => sub {
109 9     9   20 my $e = shift;
110 9 50 66     75 if( $e->got =~ m/r/ and $w->[1] ) {
111 7         23 $w->[1]->();
112             }
113 9 100 100     68 if( $e->got =~ m/w/ and $w->[2] ) {
114 3         9 $w->[2]->();
115             }
116             }
117 8         70 );
118             }
119             }
120              
121             sub unwatch_io
122             {
123 9     9 1 3566 my $self = shift;
124 9         31 my %params = @_;
125              
126 9 50       26 my $handle = $params{handle} or die "Need a handle";
127              
128 9 50       32 my $w = $self->{watch_io}{$handle} or return;
129              
130 9 100       23 if( $params{on_read_ready} ) {
131 6         23 undef $w->[1];
132             }
133              
134 9 100       19 if( $params{on_write_ready} ) {
135 5         15 undef $w->[2];
136             }
137              
138 9 100       32 my $poll = ( $w->[1] ? "r" : "" ) . ( $w->[2] ? "w" : "" );
    50          
139              
140 9 100       14 if( length $poll ) {
141 1         8 $w->[0]->poll( $poll );
142             }
143             else {
144 8         36 $w->[0]->cancel;
145 8         61 delete $self->{watch_io}{$handle};
146             }
147             }
148              
149             sub watch_time
150             {
151 30     30 1 143313 my $self = shift;
152 30         287 my %params = @_;
153              
154 30 50       149 my $code = $params{code} or croak "Expected 'code' as CODE ref";
155              
156 30         278 my $w;
157 30 100       389 if( defined $params{after} ) {
158 29         97 my $delay = $params{after};
159 29 100       111 $delay = 0 if $delay < 0;
160 29         283 $w = Event->timer( after => $delay, cb => $code );
161             }
162             else {
163 1         7 $w = Event->timer( at => $params{at}, cb => $code );
164             }
165              
166 30         8292 return $w;
167             }
168              
169             sub unwatch_time
170             {
171 19     19 1 1880 my $self = shift;
172 19         51 my ( $w ) = @_;
173              
174 19         290 $w->cancel;
175             }
176              
177             sub watch_signal
178             {
179 9     9 1 14092 my $self = shift;
180 9         74 my ( $name, $code ) = @_;
181              
182 9 100       326 exists $SIG{$name} or croak "Unrecognised signal name $name";
183              
184 8         112 my $w = Event->signal( signal => $name, cb => $code );
185 8         3225 $self->{watch_sig}{$name} = $w;
186             }
187              
188             sub unwatch_signal
189             {
190 2     2 1 1452 my $self = shift;
191 2         5 my ( $name ) = @_;
192              
193 2         25 ( delete $self->{watch_sig}{$name} )->cancel;
194             }
195              
196             sub watch_idle
197             {
198 6     6 1 4281 my $self = shift;
199 6         18 my %params = @_;
200              
201 6 50       18 my $when = delete $params{when} or croak "Expected 'when'";
202              
203 6 50       16 my $code = delete $params{code} or croak "Expected 'code' as a CODE ref";
204              
205 6 50       13 $when eq "later" or croak "Expected 'when' to be 'later'";
206              
207 6         8 my $key;
208 6         8 my $idles = $self->{watch_idle};
209 6         22 my $w = Event->timer(
210             after => 0,
211             cb => $code,
212             prio => -1,
213             );
214              
215 6         675 $key = "$w";
216 6         16 $idles->{$key} = $w;
217 6         18 return $key;
218             }
219              
220             sub unwatch_idle
221             {
222 1     1 1 4 my $self = shift;
223 1         2 my ( $id ) = @_;
224              
225 1         7 ( delete $self->{watch_idle}{$id} )->cancel;
226             }
227              
228             =head1 AUTHOR
229              
230             Paul Evans
231              
232             =cut
233              
234             0x55AA;