File Coverage

blib/lib/Event.pm
Criterion Covered Total %
statement 113 128 88.2
branch 34 58 58.6
condition 1 3 33.3
subroutine 17 20 85.0
pod 3 6 50.0
total 168 215 78.1


line stmt bran cond sub pod time code
1 24     24   78454 use strict;
  24         29  
  24         1249  
2              
3             BEGIN { # do the right thing for threads?
4 24 50   24   35 eval { require attrs; } or do {
  24         3469  
5 24         40 $INC{'attrs.pm'} = "";
6 24     0   849 *attrs::import = sub {};
7             }
8             }
9              
10             package Event;
11             require 5.008;
12 24     24   91 use base 'Exporter';
  24         30  
  24         1910  
13 24     24   84 use Carp;
  24         28  
  24         16035  
14             eval { require Carp::Heavy; }; # work around perl_call_pv bug XXX
15             our $API;
16             our $VERSION = '1.26';
17              
18             # If we inherit DynaLoader then we inherit AutoLoader; Bletch!
19             require DynaLoader;
20              
21             # DynaLoader calls dl_load_flags as a static method.
22             *dl_load_flags = DynaLoader->can('dl_load_flags');
23             (defined(&bootstrap)? \&bootstrap : \&DynaLoader::bootstrap)->
24             (__PACKAGE__, $VERSION);
25              
26             our $DebugLevel = 0;
27             our $Eval = 0; # avoid because c_callback is exempt
28             our $DIED = \&default_exception_handler;
29              
30             our @EXPORT_OK = qw(time all_events all_watchers all_running all_queued all_idle
31             one_event sweep loop unloop unloop_all sleep queue
32             queue_pending
33             QUEUES PRIO_NORMAL PRIO_HIGH NO_TIME_HIRES);
34              
35             sub import {
36 24     24   179 my $pkg = shift;
37 24         25 our $NO_TIME_HIRES;
38 24         48 my @sym;
39 24         45 for my $sym (@_) {
40 32 50       63 if ($sym eq 'NO_TIME_HIRES') {
41 0         0 $NO_TIME_HIRES = 1;
42             } else {
43 32         43 push @sym, $sym;
44             }
45             }
46              
47 24 50       60 if (!$NO_TIME_HIRES) {
48 24         29 eval { require Time::HiRes; };
  24         10269  
49 24 50       21703 if ($@ =~ /^Can\'t locate Time/) {
    50          
50             # OK, just continue
51             } elsif ($@) {
52 0 0       0 die if $@;
53             } else {
54 24         222 cache_time_api(); # hook in high precision time
55             }
56             }
57              
58 24         23753 $pkg->export_to_level(1, undef, @sym);
59             }
60              
61             # broadcast_adjust for Time::Warp? XXX
62              
63             sub _load_watcher {
64 120     120   123 my $sub = shift;
65 120         107 eval { require "Event/$sub.pm" };
  120         35348  
66 120 50       238 die if $@;
67 120 50       242 croak "Event/$sub.pm did not define Event::$sub\::new"
68             unless defined &$sub;
69 120         245 1;
70             }
71              
72             sub AUTOLOAD {
73 0     0   0 my $sub = ($Event::AUTOLOAD =~ /(\w+)$/)[0];
74 0 0       0 _load_watcher($sub) or croak $@ . ', Undefined subroutine &' . $sub;
75 0         0 carp "Autoloading with Event->$sub(...) is deprecated;
76             \tplease 'use Event::type qw($sub);' explicitly";
77 0         0 goto &$sub;
78             }
79              
80             sub default_exception_handler {
81 1     1 0 2 my ($run,$err) = @_;
82 1         1 my $desc = '?';
83 1         1 my $w;
84 1 50 33     18 if ($run and ($w = $run->w)) {
85 1         4 $desc = "`".$w->desc."'";
86             }
87 1         3 my $m = "Event: trapped error in $desc: $err";
88 1 50       5 $m .= "\n" if $m !~ m/\n$/;
89 1         4 warn $m;
90             #Carp::cluck "Event: fatal error trapped in '$desc'";
91             }
92              
93             sub verbose_exception_handler { #AUTOLOAD XXX
94 1     1 0 3 my ($e,$err) = @_;
95              
96 1         3 my $m = "Event: trapped error: $err";
97 1 50       7 $m .= "\n" if $m !~ m/\n$/;
98 1 50       8 return warn $m if !$e;
99              
100 1         3 my $w = $e->w;
101 1         7 $m .= " in $w --\n";
102              
103 1         8 for my $k ($w->attributes) {
104 11         26 $m .= sprintf "%18s: ", $k;
105 11         7 eval {
106 11         38 my $v = $w->$k();
107 11 100       49 if (!defined $v) {
    100          
108 1         2 $m .= '';
109             } elsif ($v =~ /^-?\d+(\.\d+)?$/) {
110 5         10 $m .= $v;
111             } else {
112 5         10 $m .= "'$v'";
113             }
114             };
115 11 50       13 if ($@) { $m .= "[$@]"; $@=''; }
  0         0  
  0         0  
116 11         11 $m .= "\n";
117             }
118 1         6 warn $m;
119             }
120              
121             sub sweep {
122 3 50   3 1 500597 my $prio = @_ ? shift : QUEUES();
123 3         22 queue_pending();
124 3         20 my $errsv = '';
125 3         3 while (1) {
126 5         6 eval { $@ = $errsv; _empty_queue($prio) };
  5         13  
  5         26  
127 5         555 $errsv = $@;
128 5 100       13 if ($@) {
129             # if ($Event::DebugLevel >= 2) {
130             # my $e = all_running();
131             # warn "Event: '$e->{desc}' died with: $@";
132             # }
133             next
134 2         2 }
135 3         47 last;
136             }
137             }
138              
139 24     24   180 use vars qw($Result $TopResult);
  24         33  
  24         1232  
140              
141             my $loop_timer;
142             sub loop {
143 24     24   10144 use integer;
  24         185  
  24         87  
144 117 100   117 1 13844 if (@_) {
145 2         4 my $how_long = shift;
146 2 100       11 if (!$loop_timer) {
147             $loop_timer = Event->timer(desc => "Event::loop timeout",
148             after => $how_long,
149 1     1   29 cb => sub { unloop($how_long) },
150 1         14 parked=>1);
151 1         5 $loop_timer->prio(PRIO_HIGH());
152             } else {
153 1         20 $loop_timer->at(Event::time() + $how_long),
154             }
155 2         17 $loop_timer->start;
156             }
157 117         94 $TopResult = undef; # allow re-entry of loop after unloop_all
158 117         86 local $Result = undef;
159 117         131 _incr_looplevel();
160 117         98 my $errsv = '';
161 117         106 while (1) {
162             # like G_EVAL | G_KEEPERR
163 121         109 eval { $@ = $errsv; _loop() };
  121         92  
  121         1625845  
164 121         6416393 $errsv = $@;
165 121 100       199 if ($@) {
166 4 50       11 warn "Event::loop caught: $@"
167             if $Event::DebugLevel >= 4;
168             next
169 4         19 }
170 117         97 last;
171             }
172 117         131 _decr_looplevel();
173 117 100       166 $loop_timer->stop if $loop_timer;
174 117         100 my $r = $Result;
175 117 100       160 $r = $TopResult if !defined $r;
176 117 0       159 warn "Event: unloop(".(defined $r?$r:'').")\n"
    50          
177             if $Event::DebugLevel >= 3;
178 117         287 $r
179             }
180              
181             sub add_hooks {
182 123 100   123 1 509 shift if @_ & 1; #?
183 123         377 while (@_) {
184 4         5 my $k = shift;
185 4         4 my $v = shift;
186 4 50       7 croak "$v must be CODE" if ref $v ne 'CODE';
187 4         14 _add_hook($k, $v);
188             }
189             }
190              
191 24     24   6849 END { $_->cancel for all_watchers() } # buggy? XXX
192              
193             package Event::Event::Io;
194 24     24   7408 use vars qw(@ISA);
  24         28  
  24         1186  
195             @ISA = 'Event::Event';
196              
197             package Event::Event::Dataful;
198 24     24   97 use vars qw(@ISA);
  24         28  
  24         3779  
199             @ISA = 'Event::Event';
200              
201             package Event;
202             require Event::Watcher;
203             _load_watcher($_) for qw(idle io signal timer var);
204              
205             # Provide hints to Inline.pm for usage:
206             # use Inline with => 'Event';
207             sub Inline {
208 0     0 0   my ($class, $language) = @_;
209 0 0         return if $language ne 'C'; # Inline gives good error message
210 0           require Event::MakeMaker;
211 0           my $path = $Event::MakeMaker::installsitearch;
212 0           require Config;
213 0           my $so = $Config::Config{so};
214             return {
215 0           INC => "-I $path/Event",
216             TYPEMAPS => "$path/Event/typemap",
217             MYEXTLIB => "$path/auto/Event/Event.$so",
218             AUTO_INCLUDE => '#include "EventAPI.h"',
219             BOOT => 'I_EVENT_API("Inline");',
220             };
221             }
222              
223             1;