The docs don't seem to mention what happens to an Event loop() if there
are no event sources anymore. I hoped it would unloop automagically, and
it at least *seemed* to until I tried:
#!/usr/bin/perl -wl
use strict;
use Event qw(loop unloop);
my $read_refs;
unless (@ARGV) {
Event->timer(after => 0.1, cb => sub {
print STDERR "auto exit";
# unloop;
});
loop();
print STDERR "exited";
}
my $hit = 0;
pipe(local *RD, local *WR) || die "Pipe: $!";
my $workers = 5;
my @count = (0) x ($workers+1);
my @wid;
sub fun {
$count[shift]++;
if (++$hit == 10) {
$_->cancel for @wid;
unloop();
} elsif ($hit > 10) {
print STDERR "BAD $hit alarm [EMAIL PROTECTED]";
exit if $hit > 20;
}
}
for my $n (1..$workers) {
my $alarm;
$alarm = sub {
$wid[$n] = Event->timer(after => 0, cb => $alarm);
fun($n);
};
$wid[$n] = Event->timer(after => 0, cb => $alarm);
}
$wid[0] = Event->io(fd => \*RD, poll => "r", cb => sub { fun(0) });
close WR;
loop;
close RD;
print STDERR "Good alarm [EMAIL PROTECTED]";
Running this with an argument gives the sort of expected output:
Good alarm count=2 2 2 2 1 1
Running it with an argument first lets a loop exit by itself,
but then it gives:
auto exit
exited
BAD 11 alarm count=2 2 2 2 2 1
BAD 12 alarm count=2 2 2 2 2 2
BAD 13 alarm count=2 2 2 2 3 2
BAD 14 alarm count=2 2 2 2 3 3
BAD 15 alarm count=2 2 2 2 4 3
BAD 16 alarm count=2 2 2 2 4 4
BAD 17 alarm count=2 2 2 2 5 4
BAD 18 alarm count=2 2 2 2 5 5
BAD 19 alarm count=2 2 2 2 6 5
BAD 20 alarm count=2 2 2 2 6 6
BAD 21 alarm count=2 2 2 2 7 6
(it would continue counting indefinitely if I didn't force an exit).
Commenting the unloop() at the start back in makes it work again.
So I thought that maybe the problem here was just not doing an unloop.
But a bit later I found this:
#!/usr/bin/perl -wl
use strict;
use Event qw(loop unloop);
# Set up an infinite source of read events
pipe(local *RD, local *WR) || die "pipe: $!";
close WR;
my $hit = 0;
my @count = (0) x 6;
my @wid;
sub count {
print STDERR "alarm @count";
$count[shift]++;
if (++$hit == 10) {
$wid[0]->cancel;
$wid[$_]->cancel for 1..5;
unloop();
} elsif ($hit > 20) {
print STDERR ("Running too much, probably infinite, alarm [EMAIL PROTECTED]");
exit;
}
}
$wid[0] = Event->io(fd => \*RD, poll => "r", cb => sub { count(0) });
for my $n (1..5) {
my $alarm;
$alarm = sub {
$wid[$n] = Event->timer(after => 0, cb => $alarm);
count($n);
};
$wid[$n] = Event->timer(after => 0, cb => $alarm);
}
loop;
print STDERR "-" x 70;
# Some dummy work for the second loop. Doesn't matter if you give this or not.
Event->timer(after => 1000, cb => sub { unloop });
loop;
Which sets up a file listener and 5 alarms that keep retriggering
themselves. After a certain count I unloop, and start a simple second loop.
However, in that second loop two of the canceled alarms keep going off:
alarm 0 0 0 0 0 0
alarm 1 0 0 0 0 0
alarm 1 1 0 0 0 0
alarm 1 1 1 0 0 0
alarm 1 1 1 1 0 0
alarm 1 1 1 1 1 0
alarm 1 1 1 1 1 1
alarm 2 1 1 1 1 1
alarm 2 2 1 1 1 1
alarm 2 2 2 1 1 1
----------------------------------------------------------------------
alarm 2 2 2 2 1 1
alarm 2 2 2 2 2 1
alarm 2 2 2 2 2 2
alarm 2 2 2 2 3 2
alarm 2 2 2 2 3 3
alarm 2 2 2 2 4 3
alarm 2 2 2 2 4 4
alarm 2 2 2 2 5 4
alarm 2 2 2 2 5 5
alarm 2 2 2 2 6 5
alarm 2 2 2 2 6 6
The effect doesn't happen if I use an alarm with an interval of 0 instead
of retriggering myself. It also doesn't happen if I don't have the very
busy fileevent handler.
So can't I use loop() twice ? Or am I using ->timer wrong somehow ?
Or is this an Event bug ?
(all of this is with Event version 1.0 under perl 5.8.2 on a linux machine)