Working with Margo timers

In some contexts, it may be useful to schedule a function to be invoked at a later time. This feature is provided by Margo timers. The code bellow showcases this functionality.

client.c (show/hide)

#include <assert.h>
#include <stdio.h>
#include <margo.h>
#include <margo-timer.h>
#include <margo-logging.h>

void my_callback(void* uargs) {
    margo_instance_id mid = (margo_instance_id)uargs;
    margo_info(mid, "Callback called");
}

int main(int argc, char** argv)
{
    margo_instance_id mid = margo_init("tcp",MARGO_CLIENT_MODE, 0, 0);
    margo_set_log_level(mid, MARGO_LOG_INFO);

    margo_timer_t timer = MARGO_TIMER_NULL;

    margo_timer_create(mid, my_callback, (void*)mid, &timer);
    margo_info(mid, "Timer created");

    margo_timer_start(timer, 1000);
    margo_info(mid, "Timer submitted");

    margo_thread_sleep(mid, 500);
    margo_info(mid, "This is printed before the callback");

    margo_thread_sleep(mid, 700);
    margo_info(mid, "This is printed after the callback");

    margo_timer_start(timer, 1000);
    margo_info(mid, "Timer resubmitted");

    margo_thread_sleep(mid, 500);

    margo_timer_cancel(timer);
    margo_info(mid, "Timer was cancelled");

    margo_thread_sleep(mid, 700);
    margo_info(mid, "No callback should have been printed");

    margo_timer_destroy(timer);

    margo_finalize(mid);

    return 0;
}

Important

Timers rely on the progress loop to be running. Hence if some other ULTs keep the progress loop busy, the timer will be delayed. The provided timeout value is only a lower bound on the time a timer has to wait before triggering its callback.

Important

As shown above, a timer can be restarted after its callback has been called or after being cancelled. The user must ensure that the timer is ready to be restarted before calling margo_timer_start() again, otherwise this call will return an error.

Note

It is possible to call margo_timer_start() within a timer callback to restart the timer. Hence if you need a callback to be called after 1, 2, and 3 seconds, you can either create 3 timers that you start with a different timeout value, or you can have a single timer restart itself twice with a 1 second timeout each time.