alternate approach to timer inaccuracy due to cached times

Denis Bilenko denis.bilenko at
Fri Oct 14 13:34:47 CEST 2011

Here's smaller example that demonstrates the issue, with just libev/C:

libev-timer$ cat main.c
#include <unistd.h>
#include "ev.h"

static void timer_callback(struct ev_loop *_loop, void *watcher, int
revents) { }

int main(int argc, char** argv) {
    struct ev_timer watcher;
    struct ev_loop * loop = ev_default_loop(0);
    ev_timer_init(&watcher, (void*)timer_callback, 10.0, 0.0);
    ev_timer_start(loop, &watcher);
    ev_run(loop, 0);
    return 0;

libev-timer$ time ./a.out

real	0m10.004s
user	0m0.000s
sys	0m0.000s

So the timer was set to fire in 10 seconds but fired in 3 seconds.

On Fri, Oct 14, 2011 at 3:59 PM, Marc Lehmann <schmorp at> wrote:
> I do think I understand you, and I do maintain this is a design shortcoming
> in gevent that is not shared by other code based on libev (or other event
> libraries).

I fail to see how it's a design shortcoming in gevent. It could be
that it's more likely to happen
in Python because there are more likely to be longer pauses of CPU
work. If you still think there's
more than that, I'd like to hear it.

Here's how the problem manifests itself in gevent:
time.sleep(7)  # system call sleep
gevent.sleep(10)  # this uses ev_timer to wake up the coroutine. it
sleeps for 3 seconds instead.

Your Perl's Coro library probably has sleep() function that uses
ev_timer as well? If that's the case,
it's susceptible to this issue the same way.

I think it would be better for libev is to use future timestamp
instead of past timestamp.
I think it would be better because timeouts firing later than
specified are usually not fatal for the application while timeouts
firing earlier usually are.

Are there any good reasons to prefer the past timestamp instead of the
future one?

Shaun, your patch does not seem to work for me with the above program
- the callback is not called at all if the patch is applied.

More information about the libev mailing list