File Coverage

blib/lib/Net/Curl/Simple/Async.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Net::Curl::Simple::Async;
2              
3 1     1   1209 use strict; no strict 'refs';
  1     1   2  
  1         37  
  1         5  
  1         1  
  1         24  
4 1     1   5 use warnings; no warnings 'redefine';
  1     1   1  
  1         20  
  1         5  
  1         1  
  1         25  
5 1     1   346 use Net::Curl;
  0            
  0            
6              
7             our $VERSION = '0.13';
8              
9             sub warn_noasynchdns($) { warn @_ }
10              
11              
12             # load specified backend (left) if appropriate module (right)
13             # is loaded already
14             my @backends = (
15             # Coro backends, CoroEV is preffered, but let's play it safe
16             CoroEV => 'Coro::EV',
17             AnyEvent => 'Coro::AnyEvent',
18             AnyEvent => 'Coro::Event',
19             CoroEV => 'Coro',
20             AnyEvent => 'Coro',
21             Select => 'Coro',
22              
23             # backends we support directly
24             EV => 'EV',
25             Irssi => 'Irssi',
26             AnyEvent => 'AnyEvent',
27              
28             # AnyEvent supports some implementations we don't
29             AnyEvent => 'AnyEvent::Impl::Perl',
30             AnyEvent => 'Cocoa::EventLoop',
31             AnyEvent => 'Event',
32             AnyEvent => 'Event::Lib',
33             AnyEvent => 'Glib',
34             AnyEvent => 'IO::Async::Loop',
35             AnyEvent => 'Qt',
36             AnyEvent => 'Tk',
37              
38             # POE::Loop::* implementations, our backend stinks a bit
39             # so try AnyEvent first
40             AnyEvent => 'POE::Kernel',
41             AnyEvent => 'Prima',
42             AnyEvent => 'Wx',
43              
44             # some POE::Loop::* implementations,
45             # AnyEvent is preffered as it gives us a more
46             # direct access to most backends
47             POE => 'POE::Kernel',
48             POE => 'Event',
49             POE => 'Event::Lib',
50             POE => 'Glib',
51             POE => 'Gtk', # not gtk2
52             POE => 'Prima',
53             POE => 'Tk',
54             POE => 'Wx',
55              
56             # forced backends: try to load if nothing better detected
57             EV => undef, # most efficient implementation
58             AnyEvent => undef, # AnyEvent may have some nice alternative
59             Select => undef, # will work everywhere and much faster than POE
60             );
61              
62             sub import
63             {
64             my $class = shift;
65             return if not @_;
66             # force some implementation
67             @backends = map +($_, undef), @_;
68             }
69              
70             my $multi;
71             sub multi()
72             {
73             while ( my ( $impl, $pkg ) = splice @backends, 0, 2 ) {
74             if ( not defined $pkg or defined ${ $pkg . '::VERSION' } ) {
75             my $implpkg = __PACKAGE__ . '::' . $impl;
76             eval "require $implpkg";
77             next if $@;
78             eval {
79             $multi = $implpkg->new();
80             };
81             last if $multi;
82             }
83             }
84             @backends = ();
85             die "Could not load " . __PACKAGE__ . " implementation\n"
86             unless $multi;
87              
88             warn_noasynchdns "Please rebuild libcurl with AsynchDNS to avoid blocking"
89             . " DNS requests\n" unless Net::Curl::Simple::can_asynchdns;
90              
91             *multi = sub () { $multi };
92              
93             return $multi;
94             };
95              
96             END {
97             # destroy multi object before global destruction
98             if ( $multi ) {
99             foreach my $easy ( $multi->handles ) {
100             $multi->remove_handle( $easy );
101             }
102             $multi = undef;
103             }
104             }
105              
106             1;
107              
108             __END__