vibe-d / eventcore

High performance proactor event loop abstraction library
MIT License
60 stars 42 forks source link

Timer callback resets on every firing and should be rearmed to continue #172

Closed drug007 closed 3 years ago

drug007 commented 3 years ago

OS: windows 8 x64

It looks like timer continue to work but callback is not called. Or it is the intended behaviour?

import eventcore.core;
import eventcore.internal.utils;
import core.time : Duration, msecs, seconds;

void main()
{
    print("Starting up...");

    auto timer = eventDriver.timers.create;

    TimerCallback dg = (TimerID tid) nothrow {
        print("%s", tid);
    };

    eventDriver.timers.wait(timer, dg);
    eventDriver.timers.set(timer, 1.seconds, 1.seconds);

        while (eventDriver.core.waiterCount)
    {
        auto rc = eventDriver.core.processEvents(Duration.max);
        print("rc : %s", rc);
        // eventDriver.timers.wait(timer, dg);
    }
}

it outputs:

0
rc : idle
rc : idle
rc : idle
rc : idle

It seems that the timer is still alive but its callback is not called anymore. If you uncomment the commented line it works as expected.

s-ludwig commented 3 years ago

This is intended behavior, which should be explicitly documented. There are one or two exceptions to this rule in the library, but generally:

  1. If cancel is not invoked, the callback is guaranteed to be called exactly once
  2. If the corresponding cancel is called before the callback has been invoked, the callback will not be called at all

This is important for the fiber based code in vibe.d to be able to reliably implement scoped waiting for events. It might make sense though to add a higher-level timer API akin to eventcore.socket that provides an additional method that automatically calls wait again, for cases where the callback based API is used directly.