| line | stmt | bran | cond | sub | pod | time | code | 
| 1 | 25 |  |  | 25 |  | 200079 | use strict; | 
|  | 25 |  |  |  |  | 253 |  | 
|  | 25 |  |  |  |  | 1988 |  | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | BEGIN {  # do the right thing for threads? | 
| 4 | 25 | 50 |  | 25 |  | 86 | eval { require attrs; } or do { | 
|  | 25 |  |  |  |  | 4971 |  | 
| 5 | 25 |  |  |  |  | 98 | $INC{'attrs.pm'} = ""; | 
| 6 | 25 |  |  | 0 |  | 1209 | *attrs::import = sub {}; | 
| 7 |  |  |  |  |  |  | } | 
| 8 |  |  |  |  |  |  | } | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | package Event; | 
| 11 |  |  |  |  |  |  | require 5.008; | 
| 12 | 25 |  |  | 25 |  | 160 | use base 'Exporter'; | 
|  | 25 |  |  |  |  | 47 |  | 
|  | 25 |  |  |  |  | 3842 |  | 
| 13 | 25 |  |  | 25 |  | 188 | use Carp; | 
|  | 25 |  |  |  |  | 43 |  | 
|  | 25 |  |  |  |  | 28110 |  | 
| 14 |  |  |  |  |  |  | eval { require Carp::Heavy; };  # work around perl_call_pv bug XXX | 
| 15 |  |  |  |  |  |  | our $API; | 
| 16 |  |  |  |  |  |  | our $VERSION = '1.28'; | 
| 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 |  | 275 | my $pkg = shift; | 
| 37 | 24 |  |  |  |  | 44 | our $NO_TIME_HIRES; | 
| 38 | 24 |  |  |  |  | 45 | my @sym; | 
| 39 | 24 |  |  |  |  | 65 | for my $sym (@_) { | 
| 40 | 32 | 50 |  |  |  | 81 | if ($sym eq 'NO_TIME_HIRES') { | 
| 41 | 0 |  |  |  |  | 0 | $NO_TIME_HIRES = 1; | 
| 42 |  |  |  |  |  |  | } else { | 
| 43 | 32 |  |  |  |  | 70 | push @sym, $sym; | 
| 44 |  |  |  |  |  |  | } | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 24 | 50 |  |  |  | 79 | if (!$NO_TIME_HIRES) { | 
| 48 | 24 |  |  |  |  | 39 | eval { require Time::HiRes; }; | 
|  | 24 |  |  |  |  | 13638 |  | 
| 49 | 24 | 50 |  |  |  | 35226 | if ($@ =~ /^Can\'t locate Time/) { | 
|  |  | 50 |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | # OK, just continue | 
| 51 |  |  |  |  |  |  | } elsif ($@) { | 
| 52 | 0 | 0 |  |  |  | 0 | die if $@; | 
| 53 |  |  |  |  |  |  | } else { | 
| 54 | 24 |  |  |  |  | 440 | cache_time_api();  # hook in high precision time | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  | } | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 24 |  |  |  |  | 33944 | $pkg->export_to_level(1, undef, @sym); | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | # broadcast_adjust for Time::Warp? XXX | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | sub _load_watcher { | 
| 64 | 125 |  |  | 125 |  | 220 | my $sub = shift; | 
| 65 | 125 |  |  |  |  | 219 | eval { require "Event/$sub.pm" }; | 
|  | 125 |  |  |  |  | 64653 |  | 
| 66 | 125 | 50 |  |  |  | 388 | die if $@; | 
| 67 | 125 | 50 |  |  |  | 339 | croak "Event/$sub.pm did not define Event::$sub\::new" | 
| 68 |  |  |  |  |  |  | unless defined &$sub; | 
| 69 | 125 |  |  |  |  | 358 | 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 | 4 | my ($run,$err) = @_; | 
| 82 | 1 |  |  |  |  | 3 | my $desc = '?'; | 
| 83 | 1 |  |  |  |  | 2 | my $w; | 
| 84 | 1 | 50 | 33 |  |  | 40 | if ($run and ($w = $run->w)) { | 
| 85 | 1 |  |  |  |  | 11 | $desc = "`".$w->desc."'"; | 
| 86 |  |  |  |  |  |  | } | 
| 87 | 1 |  |  |  |  | 4 | my $m = "Event: trapped error in $desc: $err"; | 
| 88 | 1 | 50 |  |  |  | 14 | $m .= "\n" if $m !~ m/\n$/; | 
| 89 | 1 |  |  |  |  | 10 | warn $m; | 
| 90 |  |  |  |  |  |  | #Carp::cluck "Event: fatal error trapped in '$desc'"; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | sub verbose_exception_handler { #AUTOLOAD XXX | 
| 94 | 1 |  |  | 1 | 0 | 5 | my ($e,$err) = @_; | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 1 |  |  |  |  | 4 | my $m = "Event: trapped error: $err"; | 
| 97 | 1 | 50 |  |  |  | 8 | $m .= "\n" if $m !~ m/\n$/; | 
| 98 | 1 | 50 |  |  |  | 10 | return warn $m if !$e; | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 1 |  |  |  |  | 5 | my $w = $e->w; | 
| 101 | 1 |  |  |  |  | 8 | $m .= "  in $w --\n"; | 
| 102 |  |  |  |  |  |  |  | 
| 103 | 1 |  |  |  |  | 12 | for my $k ($w->attributes) { | 
| 104 | 11 |  |  |  |  | 28 | $m .= sprintf "%18s: ", $k; | 
| 105 | 11 |  |  |  |  | 14 | eval { | 
| 106 | 11 |  |  |  |  | 52 | my $v = $w->$k(); | 
| 107 | 11 | 100 |  |  |  | 96 | if (!defined $v) { | 
|  |  | 100 |  |  |  |  |  | 
| 108 | 1 |  |  |  |  | 2 | $m .= ''; | 
| 109 |  |  |  |  |  |  | } elsif ($v =~ /^-?\d+(\.\d+)?$/) { | 
| 110 | 5 |  |  |  |  | 13 | $m .= $v; | 
| 111 |  |  |  |  |  |  | } else { | 
| 112 | 5 |  |  |  |  | 13 | $m .= "'$v'"; | 
| 113 |  |  |  |  |  |  | } | 
| 114 |  |  |  |  |  |  | }; | 
| 115 | 11 | 50 |  |  |  | 29 | if ($@) { $m .= "[$@]"; $@=''; } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 116 | 11 |  |  |  |  | 16 | $m .= "\n"; | 
| 117 |  |  |  |  |  |  | } | 
| 118 | 1 |  |  |  |  | 7 | warn $m; | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | sub sweep { | 
| 122 | 3 | 50 |  | 3 | 1 | 500730 | my $prio = @_ ? shift : QUEUES(); | 
| 123 | 3 |  |  |  |  | 29 | queue_pending(); | 
| 124 | 3 |  |  |  |  | 46 | my $errsv = ''; | 
| 125 | 3 |  |  |  |  | 31 | while (1) { | 
| 126 | 5 |  |  |  |  | 13 | eval { $@ = $errsv; _empty_queue($prio) }; | 
|  | 5 |  |  |  |  | 10 |  | 
|  | 5 |  |  |  |  | 31 |  | 
| 127 | 5 |  |  |  |  | 548 | $errsv = $@; | 
| 128 | 5 | 100 |  |  |  | 26 | if ($@) { | 
| 129 |  |  |  |  |  |  | #	    if ($Event::DebugLevel >= 2) { | 
| 130 |  |  |  |  |  |  | #		my $e = all_running(); | 
| 131 |  |  |  |  |  |  | #		warn "Event: '$e->{desc}' died with: $@"; | 
| 132 |  |  |  |  |  |  | #	    } | 
| 133 |  |  |  |  |  |  | next | 
| 134 | 2 |  |  |  |  | 4 | } | 
| 135 | 3 |  |  |  |  | 152 | last; | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 25 |  |  | 25 |  | 237 | use vars qw($Result $TopResult); | 
|  | 25 |  |  |  |  | 62 |  | 
|  | 25 |  |  |  |  | 1935 |  | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | my $loop_timer; | 
| 142 |  |  |  |  |  |  | sub loop { | 
| 143 | 25 |  |  | 25 |  | 14726 | use integer; | 
|  | 25 |  |  |  |  | 380 |  | 
|  | 25 |  |  |  |  | 145 |  | 
| 144 | 117 | 100 |  | 117 | 1 | 13512 | if (@_) { | 
| 145 | 2 |  |  |  |  | 5 | my $how_long = shift; | 
| 146 | 2 | 100 |  |  |  | 10 | if (!$loop_timer) { | 
| 147 |  |  |  |  |  |  | $loop_timer = Event->timer(desc => "Event::loop timeout", | 
| 148 |  |  |  |  |  |  | after => $how_long, | 
| 149 | 1 |  |  | 1 |  | 46 | cb => sub { unloop($how_long) }, | 
| 150 | 1 |  |  |  |  | 11 | parked=>1); | 
| 151 | 1 |  |  |  |  | 5 | $loop_timer->prio(PRIO_HIGH()); | 
| 152 |  |  |  |  |  |  | } else { | 
| 153 | 1 |  |  |  |  | 16 | $loop_timer->at(Event::time() + $how_long), | 
| 154 |  |  |  |  |  |  | } | 
| 155 | 2 |  |  |  |  | 13 | $loop_timer->start; | 
| 156 |  |  |  |  |  |  | } | 
| 157 | 117 |  |  |  |  | 186 | $TopResult = undef;    # allow re-entry of loop after unloop_all | 
| 158 | 117 |  |  |  |  | 186 | local $Result = undef; | 
| 159 | 117 |  |  |  |  | 302 | _incr_looplevel(); | 
| 160 | 117 |  |  |  |  | 181 | my $errsv = ''; | 
| 161 | 117 |  |  |  |  | 195 | while (1) { | 
| 162 |  |  |  |  |  |  | # like G_EVAL | G_KEEPERR | 
| 163 | 121 |  |  |  |  | 252 | eval { $@ = $errsv; _loop() }; | 
|  | 121 |  |  |  |  | 202 |  | 
|  | 121 |  |  |  |  | 1878057 |  | 
| 164 | 121 |  |  |  |  | 6508077 | $errsv = $@; | 
| 165 | 121 | 100 |  |  |  | 321 | if ($@) { | 
| 166 | 4 | 50 |  |  |  | 17 | warn "Event::loop caught: $@" | 
| 167 |  |  |  |  |  |  | if $Event::DebugLevel >= 4; | 
| 168 |  |  |  |  |  |  | next | 
| 169 | 4 |  |  |  |  | 10 | } | 
| 170 | 117 |  |  |  |  | 177 | last; | 
| 171 |  |  |  |  |  |  | } | 
| 172 | 117 |  |  |  |  | 258 | _decr_looplevel(); | 
| 173 | 117 | 100 |  |  |  | 277 | $loop_timer->stop if $loop_timer; | 
| 174 | 117 |  |  |  |  | 181 | my $r = $Result; | 
| 175 | 117 | 100 |  |  |  | 226 | $r = $TopResult if !defined $r; | 
| 176 | 117 | 0 |  |  |  | 232 | warn "Event: unloop(".(defined $r?$r:'').")\n" | 
|  |  | 50 |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | if $Event::DebugLevel >= 3; | 
| 178 | 117 |  |  |  |  | 781 | $r | 
| 179 |  |  |  |  |  |  | } | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | sub add_hooks { | 
| 182 | 128 | 100 |  | 128 | 1 | 823 | shift if @_ & 1; #? | 
| 183 | 128 |  |  |  |  | 448 | while (@_) { | 
| 184 | 4 |  |  |  |  | 9 | my $k = shift; | 
| 185 | 4 |  |  |  |  | 5 | my $v = shift; | 
| 186 | 4 | 50 |  |  |  | 11 | croak "$v must be CODE" if ref $v ne 'CODE'; | 
| 187 | 4 |  |  |  |  | 17 | _add_hook($k, $v); | 
| 188 |  |  |  |  |  |  | } | 
| 189 |  |  |  |  |  |  | } | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 25 |  |  | 25 |  | 9890 | END { $_->cancel for all_watchers() } # buggy? XXX | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | package Event::Event::Io; | 
| 194 | 25 |  |  | 25 |  | 10416 | use vars qw(@ISA); | 
|  | 25 |  |  |  |  | 60 |  | 
|  | 25 |  |  |  |  | 1904 |  | 
| 195 |  |  |  |  |  |  | @ISA = 'Event::Event'; | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | package Event::Event::Dataful; | 
| 198 | 25 |  |  | 25 |  | 189 | use vars qw(@ISA); | 
|  | 25 |  |  |  |  | 67 |  | 
|  | 25 |  |  |  |  | 5631 |  | 
| 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 | 3 |  |  | 3 | 0 | 856 | my ($class, $language) = @_; | 
| 209 | 3 |  |  |  |  | 448 | require Event::MakeMaker; | 
| 210 | 3 |  |  |  |  | 7 | my $path = $Event::MakeMaker::installsitearch; | 
| 211 | 3 |  |  |  |  | 11 | require Config; | 
| 212 | 3 |  |  |  |  | 20 | my $so = $Config::Config{so}; | 
| 213 |  |  |  |  |  |  | return { | 
| 214 | 3 |  |  |  |  | 28 | INC => "-I $path/Event", | 
| 215 |  |  |  |  |  |  | TYPEMAPS => "$path/Event/typemap", | 
| 216 |  |  |  |  |  |  | MYEXTLIB => "$path/auto/Event/Event.$so", | 
| 217 |  |  |  |  |  |  | AUTO_INCLUDE => '#include "EventAPI.h"', | 
| 218 |  |  |  |  |  |  | BOOT => 'I_EVENT_API("Inline");', | 
| 219 |  |  |  |  |  |  | }; | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | 1; |