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)

Reply via email to