Skip Menu |

This queue is for tickets about the IO-Async CPAN distribution.

Report information
The Basics
Id: 100927
Status: resolved
Priority: 0/
Queue: IO-Async

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.64
Fixed in: 0.68



Subject: IO::Async::Timer::Periodic 'first_interval' only applies for first start
If you ->stop and ->start a Periodic timer a second time, it forget the "first_interval". -- Paul Evans
Fixed. -- Paul Evans
Subject: rt100927.patch
=== modified file 'lib/IO/Async/Timer/Periodic.pm' --- lib/IO/Async/Timer/Periodic.pm 2015-06-01 14:12:39 +0000 +++ lib/IO/Async/Timer/Periodic.pm 2015-07-31 18:41:37 +0000 @@ -166,42 +166,46 @@ $self->SUPER::configure( %params ); } -sub _next_interval +sub _reschedule { my $self = shift; - return $self->{first_interval} if defined $self->{first_interval}; - return $self->{interval}; + + my $now = $self->loop->time; + my $resched = $self->{reschedule}; + + my $next_interval = $self->{is_first} && defined $self->{first_interval} + ? $self->{first_interval} : $self->{interval}; + delete $self->{is_first}; + + if( !defined $self->{next_time} ) { + $self->{next_time} = $now + $next_interval; + } + elsif( $resched eq "hard" ) { + $self->{next_time} += $next_interval; + } + elsif( $resched eq "skip" ) { + # How many ticks are needed? + my $ticks = POSIX::ceil( $now - $self->{next_time} ); + # $self->{last_ticks} = $ticks; + $self->{next_time} += $next_interval * $ticks; + } + elsif( $resched eq "drift" ) { + $self->{next_time} = $now + $next_interval; + } + + $self->SUPER::start; } sub start { my $self = shift; + $self->{is_first} = 1; + # Only actually define a time if we've got a loop; otherwise it'll just # become start-pending. We'll calculate it properly when it gets added to # the Loop - if( my $loop = $self->loop ) { - my $now = $loop->time; - my $resched = $self->{reschedule}; - - if( !defined $self->{next_time} ) { - $self->{next_time} = $now + $self->_next_interval; - } - elsif( $resched eq "hard" ) { - $self->{next_time} += $self->_next_interval; - } - elsif( $resched eq "skip" ) { - # How many ticks are needed? - my $ticks = POSIX::ceil( $now - $self->{next_time} ); - # $self->{last_ticks} = $ticks; - $self->{next_time} += $self->_next_interval * $ticks; - } - elsif( $resched eq "drift" ) { - $self->{next_time} = $now + $self->_next_interval; - } - } - - $self->SUPER::start; + $self->_reschedule if $self->loop; } sub stop @@ -219,15 +223,13 @@ return $self->_capture_weakself( sub { my $self = shift or return; - undef $self->{first_interval}; - undef $self->{id}; my $ok = eval { $self->invoke_event( on_tick => ); 1 } or my $e = $@; # detect ->stop - $self->start if defined $self->{next_time}; + $self->_reschedule if defined $self->{next_time}; die $e if !$ok; } );
Released -- Paul Evans