Skip Menu |

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

Report information
The Basics
Id: 53281
Status: resolved
Priority: 0/
Queue: IO-Async-Loop-Glib

People
Owner: Nobody in particular
Requestors: g.schlmm [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.17
Fixed in: (no value)



Subject: Periodic Timer stopping some code is blocking longer than the interval
Hi,

The periodic timer isnt working anymore, if some code is taking longer than the interval of the timer
But it is still reporting that it is running
Glib::Timeout->add() works as expected and doesnt stop
The other loops (Polll and Select) are also working

see attachment for an example

perl -v:
This is perl, v5.10.1 (*) built for i486-linux-thread-multi
uname -a:
Linux delltop 2.6.31.5-mine #1 SMP PREEMPT Tue Nov 3 12:24:17 CET 2009 i686 Intel(R) Core(TM)2 Duo CPU     T7500  @ 2.20GHz GenuineIntel GNU/Linux

Subject: glib-periodic.pl
#!/usr/bin/perl -w use IO::Async::Loop::Glib; use IO::Async::Timer::Periodic; use IO::Async::Timer::Countdown; my $loop = IO::Async::Loop::Glib->new; my $countdown = IO::Async::Timer::Countdown->new( delay => 3, on_expire => sub { print "some code which is taking longer than the interval\n"; sleep 2; } ); $loop->add($countdown); $countdown->start; # stops if $countdown on_expire is executed my $periodic = IO::Async::Timer::Periodic->new( interval => 1, on_tick => sub { print "io-async-timer-periodic: on_tick\n"; return 1; } ); $loop->add($periodic); $periodic->start; # this works as expected Glib::Timeout->add(1000, sub { print "glib-timeout: on_tick\n"; print "periodic still running? ", $periodic->is_running, "\n"; return 1; }); $loop->loop_forever;
On Fri Jan 01 13:14:23 2010, schlmm wrote:
Show quoted text
> The periodic timer isnt working anymore, if some code is taking longer
> than the
> interval of the timer
> But it is still reporting that it is running
> Glib::Timeout->add() works as expected and doesnt stop
> The other loops (Polll and Select) are also working
>
> see attachment for an example

Ah yes; I have run that and confirmed it does indeed appear to fail.

I'll have a play with it and see what's up...

Thanks,

--

Paul Evans
On Sun Jan 03 14:00:03 2010, PEVANS wrote:
Show quoted text
> I'll have a play with it and see what's up...

Ah; I see.

Your sleep(2) causes the next time for the Timer::Periodic to go past, so when it comes to reenqueue itself it gets a negative interval. Most runloops seem to be happy with this, they'll treat it as "ASAP"; whereas Glib didn't run it - I wonder if it became unsigned and therefore a large number close to 4 billion seconds.

In any case, I've added a simple clamp to set it to zero if negative, and fix a couple of other small bugs.

Please find attached a patch that should fix these; let me know how you find it...

--

Paul Evans
Subject: fix-rt-53281.patch
=== modified file 'Build.PL' --- Build.PL 2009-10-12 02:07:15 +0000 +++ Build.PL 2010-01-03 19:42:19 +0000 @@ -7,13 +7,14 @@ ( module_name => 'IO::Async::Loop::Glib', requires => { - 'IO::Async::Loop' => 0.24, - 'Glib' => 0, - }, + 'Glib' => 0, + 'IO::Async::Loop' => 0.24, + 'Time::HiRes' => 0, + }, build_requires => { - 'Test::More' => 0, - 'IO::Async::LoopTests' => '0.24', - }, + 'Test::More' => 0, + 'IO::Async::LoopTests' => '0.24', + }, license => 'perl', create_makefile_pl => 'traditional', create_license => 1, === modified file 'lib/IO/Async/Loop/Glib.pm' --- lib/IO/Async/Loop/Glib.pm 2010-01-03 19:19:40 +0000 +++ lib/IO/Async/Loop/Glib.pm 2010-01-03 19:41:52 +0000 @@ -17,6 +17,8 @@ use Glib; +use Time::HiRes qw( time ); + =head1 NAME C<IO::Async::Loop::Glib> - use C<IO::Async> with F<Glib> or F<GTK> @@ -184,6 +186,7 @@ } my $interval = $delay * 1000; # miliseconds + $interval = 0 if $interval < 0; # clamp or Glib gets upset my $code = delete $params{code}; ref $code eq "CODE" or croak "Expected 'code' to be a CODE reference"; @@ -286,7 +289,9 @@ my $context = Glib::MainContext->default; my $ret = $context->iteration( 1 ); - Glib::Source->remove( $timerid ) unless $timed_out; + if( defined $timerid ) { + Glib::Source->remove( $timerid ) unless $timed_out; + } return $ret and not $timed_out ? 1 : 0; }
From: g.schlmm [...] gmail.com
Hi,<br /> Yes! works now like the other loops. Thank you very much<br /> In general I would like it more if the periodic timers work like Glib::Timeout, so every interval is ignored if it couldnt hit the time when it should execute (especially if you have very low intervals). But thats a design decision i guess, which is up to you :)<br /> <br /> Best regards<br /> Georg<br /> <br />
On Sun Jan 03 15:58:41 2010, schlmm wrote:
Show quoted text
> In general I would like it more if the periodic timers work like
> Glib::Timeout, so every interval is ignored if it couldnt hit the
> time when it should execute (especially if you have very low
> intervals). But thats a design decision i guess, which is up to you
> :)

Perhaps a parameter, to control this? I was also wondering if it might be useful in some applications to skip over the missing ticks, but keep a count of how many to pass it to the callback function. So at least it would know how many ticks were lost...

I'll have a think on that.

For now though I'll put an updated Loop-Glib on CPAN for you

--

Paul Evans
On Mon Jan 04 07:20:06 2010, PEVANS wrote:
Show quoted text
> For now though I'll put an updated Loop-Glib on CPAN for you

Now on CPAN:

  http://search.cpan.org/~pevans/IO-Async-Loop-Glib-0.18/

As to the periodic timer skipping ticks, I'll work on that and include it in the next IO::Async...

--

Paul Evans