File Coverage

blib/lib/Net/SIP/Dispatcher/AnyEvent.pm
Criterion Covered Total %
statement 56 65 86.1
branch 11 20 55.0
condition 3 5 60.0
subroutine 15 16 93.7
pod 6 6 100.0
total 91 112 81.2


line stmt bran cond sub pod time code
1 27     27   146 use strict;
  27         89  
  27         932  
2 27     27   143 use warnings;
  27         67  
  27         1642  
3             package Net::SIP::Dispatcher::AnyEvent;
4             {
5             $Net::SIP::Dispatcher::AnyEvent::VERSION = '0.002';
6             }
7             # ABSTRACT: AnyEvent dispatcher for Net::SIP
8              
9 27     27   55461 use AnyEvent;
  27         189790  
  27         1034  
10 27     27   21908 use Net::SIP::Dispatcher::AnyEvent::Timer;
  27         134  
  27         1554  
11 27     27   302 use Net::SIP::Util 'invoke_callback';
  27         44  
  27         2642  
12 27     27   33967 use AnyEvent::AggressiveIdle ();
  27         246182  
  27         17285  
13              
14             sub new {
15 20     20 1 35610 my $class = shift;
16 20         364 my %args = @_;
17 20   50     3231 my $self = bless {
18             _cv => AE::cv,
19             _ae_interval => $args{'_ae_interval'} || 0.2,
20             }, $class;
21              
22 20 50       257214 if ( $args{'_net_sip_compat'} ) {
23             $self->{'_idle'} = AnyEvent::AggressiveIdle::aggressive_idle {
24 0 0   0   0 exists $self->{'_stopvar'} or return;
25 0         0 foreach my $var ( @{ $self->{'_stopvar'} } ) {
  0         0  
26 0 0       0 if ( ${$var} ) {
  0         0  
27 0         0 delete $self->{'_stopvar'};
28 0         0 $self->{'_cv'}->send;
29             }
30             }
31 0         0 };
32             }
33              
34 20         200 return $self;
35             }
36              
37             sub addFD {
38 34     34 1 61847 my $self = shift;
39 34         246 my ( $fh, $cb_data, $name ) = @_;
40              
41 34 50       415 my $fn = fileno $fh or return;
42              
43             $self->{'_fd_watchers'}{$fn} = AE::io $fh, 0, sub {
44 925     925   12811822 invoke_callback( $cb_data, $fh );
45             }
46 34         1082 }
47              
48             sub delFD {
49 12     12 1 55581 my $self = shift;
50 12         44 my $fh = shift;
51 12 50       198 my $fn = fileno $fh or return;
52              
53 12         452 delete $self->{'_fd_watchers'}{$fn};
54             }
55              
56             sub add_timer {
57 35     35 1 13917 my $self = shift;
58 35         182 my ( $when, $cb_data, $repeat, $name ) = @_;
59 35 50       269 defined $repeat or $repeat = 0;
60              
61             # is $when epoch or relative?
62 35 50       155 if ( $when >= 3600*24*365 ) {
63 0         0 $when = AE::now - $when;
64             }
65              
66 35         1035 return Net::SIP::Dispatcher::AnyEvent::Timer->new(
67             $name, $when, $repeat, $cb_data
68             );
69             }
70              
71 44     44 1 2412 sub looptime { AE::now }
72              
73             sub loop {
74 38     38 1 206338 my $self = shift;
75 38         126 my ( $timeout, @stopvar ) = @_;
76              
77 38         218 $self->{'_stopvar'} = \@stopvar;
78              
79 38 100 66     677 if ( ! $self->{'_net_sip_compat'} and @stopvar ) {
80             # set up a timer to check stopvars
81             $self->{'_stopvar_timer'} = AE::timer 0, $self->{'_ae_interval'}, sub {
82 225     225   17180548 foreach my $var (@stopvar) {
83 225 100       615 if ( ${$var} ) {
  225         5104  
84 30         543 delete $self->{'_stopvar_timer'};
85 30         160 delete $self->{'_stopvar'};
86 30         767 $self->{'_cv'}->send;
87             }
88             }
89             }
90 32         574 }
91              
92 38 100       309 if ($timeout) {
93 30         62 my $timer; $timer = AE::timer $timeout, 0, sub {
94 8     8   794771 undef $timer;
95 8         173 $self->{'_cv'}->send;
96 30         366 };
97             }
98              
99 38         579 $self->{'_cv'}->recv;
100              
101             # clean up, prepare for another round
102 38         6757 $self->{'_cv'} = AE::cv;
103             }
104              
105             1;
106              
107              
108              
109             =pod
110              
111             =head1 NAME
112              
113             Net::SIP::Dispatcher::AnyEvent - AnyEvent dispatcher for Net::SIP
114              
115             =head1 VERSION
116              
117             version 0.002
118              
119             =head1 DESCRIPTION
120              
121             This module allows L to work with L as the event loop,
122             instead of its own. This means you can combine them.
123              
124             While this is the implementation itself, you probably want to use
125             L instead. You definitely want to read the documentation there
126             instead of here. Go ahead, click the link. :)
127              
128             The rest only documents how the loop implementation works. If you use this
129             directly, the only method you care about is C.
130              
131             =head1 WARNING
132              
133             The compatible mode of Net::SIP::Dispatcher::AnyEvent is pretty stressful on
134             your CPU. Please read the compatibility mode section in L.
135              
136             =head1 ATTRIBUTES
137              
138             =head2 _net_sip_compat
139              
140             Whether to be fully compatible with L with the expense of possible
141             side-effects on the CPU load of your processes. Please read compatibility mode
142             in L.
143              
144             =head2 _ae_interval
145              
146             In normal (non-compatible) mode, how often to check for stopvars.
147             Default: B<0.2> seconds.
148              
149             =head1 INTERNAL ATTRIBUTES
150              
151             These attributes have no accessors, they are saved as internal keys.
152              
153             =head2 _idle
154              
155             Hold the L object that checks stopvars.
156              
157             =head2 _stopvar
158              
159             Condition variables to be checked for stopping the loop.
160              
161             =head2 _cv
162              
163             Main condition variable allowing for looping.
164              
165             =head2 _fd_watchers
166              
167             All the watched file descriptors.
168              
169             =head2 _stopvar_timer
170              
171             Timer holding stopvar checking. Only for default non-compatible mode.
172              
173             =head1 METHODS
174              
175             =head2 new
176              
177             The object constructor. It creates a default CondVar in C<_cv> hash key,
178             and sets an aggressive idle CondVar in the C<_idle> hash key, which checks
179             the stopvars every loop cycle.
180              
181             =head2 addFD($fd, $cb_data, [$name])
182              
183             Add a file descriptor to watch input for, and a callback to run when it's ready
184             to be read.
185              
186             =head2 delFD($fd)
187              
188             Delete the watched file descriptor.
189              
190             =head2 add_timer($when, $cb_data, [$repeat], [$name])
191              
192             Create a timer to run a callback at a certain point in time. If the time is
193             considerably far (3,600 * 24 * 365 and up), it's a specific point in
194             time. Otherwise, it's a number of seconds from now.
195              
196             The C option is an optional interval for the timer.
197              
198             =head2 looptime
199              
200             Provide the event loop time.
201              
202             =head2 loop($timeout, [\@stopvars])
203              
204             Run the event loop and wait for all events to finish (whether by timeout or
205             stopvars becoming true).
206              
207             =head1 AUTHOR
208              
209             Sawyer X
210              
211             =head1 COPYRIGHT AND LICENSE
212              
213             This software is copyright (c) 2013 by Sawyer X.
214              
215             This is free software; you can redistribute it and/or modify it under
216             the same terms as the Perl 5 programming language system itself.
217              
218             =cut
219              
220              
221             __END__