AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Loop.pm view on Meta::CPAN
@timer = sort { $a->[0] <=> $b->[0] } @timer;
}
# handle all pending timers
if (@timer && $timer[0][0] <= $MNOW) {
do {
my $timer = shift @timer;
$timer->[1] && $timer->[1]($timer);
} while @timer && $timer[0][0] <= $MNOW;
} else {
# poll for I/O events, we do not do this when there
# were any pending timers to ensure that one_event returns
# quickly when some timers have been handled
my ($wait, @vec, $fds)
= (@timer && $timer[0][0] < $need_sort ? $timer[0][0] : $need_sort) - $MNOW;
$wait = $wait < MAXWAIT ? $wait + ROUNDUP : MAXWAIT;
$wait = 0 if @idle;
$fds = CORE::select
$vec[0] = $fds[0][V],
$vec[1] = $fds[1][V],
AnyEvent::WIN32 ? $vec[2] = $fds[1][V] : undef,
$wait;
_update_clock;
if ($fds > 0) {
# buggy microshit windows errornously sets exceptfds instead of writefds
$vec[1] |= $vec[2] if AnyEvent::WIN32;
# prefer write watchers, because they might reduce memory pressure.
for (1, 0) {
my $fds = $fds[$_];
# we parse the bitmask by first expanding it into
# a string of bits
for (unpack "b*", $vec[$_]) {
# and then repeatedly matching a regex against it
while (/1/g) {
# and use the resulting string position as fd
$_ && $_->[2]()
for @{ $fds->[W][(pos) - 1] || [] };
}
}
}
} elsif (AnyEvent::WIN32 && $fds && $! == AnyEvent::Util::WSAEINVAL) {
# buggy microshit windoze asks us to route around it
CORE::select undef, undef, undef, $wait if $wait;
} elsif (!@timer || $timer[0][0] > $MNOW && !$fds) {
$$$_ && $$$_->() for @idle = grep $$$_, @idle;
}
}
}
sub run {
one_event while 1;
}
sub io($$$) {
my ($fd, $write, $cb) = @_;
defined ($fd = fileno $fd)
or $fd = $_[0];
my $self = bless [
$fd,
$write,
$cb,
# q-idx
], "AnyEvent::Loop::io";
my $fds = $fds[$self->[1]];
# add watcher to fds structure
my $q = $fds->[W][$fd] ||= [];
(vec $fds->[V], $fd, 1) = 1;
$self->[3] = @$q;
push @$q, $self;
weaken $q->[-1];
$self
}
sub AnyEvent::Loop::io::DESTROY {
my ($self) = @_;
my $fds = $fds[$self->[1]];
# remove watcher from fds structure
my $fd = $self->[0];
if (@{ $fds->[W][$fd] } == 1) {
delete $fds->[W][$fd];
(vec $fds->[V], $fd, 1) = 0;
} else {
my $q = $fds->[W][$fd];
my $last = pop @$q;
if ($last != $self) {
weaken ($q->[$self->[3]] = $last);
$last->[3] = $self->[3];
}
}
}
sub timer($$$) {
my ($after, $interval, $cb) = @_;
my $self;
if ($interval) {
$self = [$MNOW + $after , sub {
$_[0][0] = List::Util::max $_[0][0] + $interval, $MNOW;
push @timer, $_[0];
weaken $timer[-1];
$need_sort = $_[0][0] if $_[0][0] < $need_sort;
&$cb;
( run in 0.754 second using v1.01-cache-2.11-cpan-5a3173703d6 )