Logo Search packages:      
Sourcecode: iacd version File versions  Download package

timer.c

#define _GNU_SOURCE

#include "config.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "timer.h"
#include "util.h"
#include "log.h"

static ti_timer_node_t *ti_root = NULL;

__inline__ int
ti_compare(ti_timer_node_t *n1, ti_timer_node_t *n2)
{
    if (n1->ti_interval.tv_sec < n2->ti_interval.tv_sec) {
        return -1; 
    } else  if (n1->ti_interval.tv_sec == n2->ti_interval.tv_sec) {
        if (n1->ti_interval.tv_usec < n2->ti_interval.tv_usec) {
            return -1;
        } else {
            return 1;
        }
    } else {
        return 1;
    }
}


void
ti_insert_node(ti_timer_node_t **src, ti_timer_node_t *n)
{
    if (!*src) {
        *src = n;
    } else {
        if (ti_compare(n, *src) < 0) {
            n->ti_next = *src;
            *src = n;
        } else {
            ti_insert_node(&((*src)->ti_next), n);
        }
    }
}

int
ti_add_callback(struct timeval *interval, void (*func)(const char *), const char *msg)
{
    ti_timer_node_t *n;
    
    n = (ti_timer_node_t *) malloc(sizeof(ti_timer_node_t));
    
    if (!n) {
        errno = ENOMEM;
        return -1;
    }
    
    memset(n, 0, sizeof(ti_timer_node_t));

    if (!(n->ti_msg = strdup(msg))) {
        errno = ENOMEM;
        return -1;
    }

    n->ti_func = func;
    gettimeofday(&n->ti_interval, NULL);
    n->ti_interval.tv_sec += interval->tv_sec;
    n->ti_interval.tv_usec += interval->tv_usec;

    if (n->ti_interval.tv_usec > 999999) {
        n->ti_interval.tv_sec++;
        n->ti_interval.tv_usec -= 1000000;
    }

    ti_insert_node(&ti_root, n);

    iac_log(IAC_DEBUG, "[   ] * Added timer %lds %ldusec calling %p\n",
        interval->tv_sec, interval->tv_usec, func);

    return 0;
}

int
p_ti_gt_now(struct timeval *tv)
{
    struct timeval now;

    gettimeofday( &now, NULL );

    if ( now.tv_sec > tv->tv_sec )
        return 1;
    else if ( now.tv_sec == tv->tv_sec )
    {
        if ( now.tv_usec > tv->tv_usec )
            return 1;
    }

    return 0;
}

void
ti_call(void)
{
    /*
     * 2002-10-25
     *
     * The timeout is now max. 5 seconds, this means a timeout doesnt mean
     * that a timer has expired.
     */
    ti_timer_node_t *t;
    
    if (ti_root)  {

        if ( p_ti_gt_now( &ti_root->ti_interval ) )
        {
            iac_log(IAC_DEBUG, "[   ] * Timeout! Calling %p\n", ti_root->ti_func);

            ti_root->ti_func(ti_root->ti_msg);
            t = ti_root;
            ti_root = ti_root->ti_next;
            free(t->ti_msg);
            free(t);
        }
        else
        {
            iac_log( IAC_DEBUG, "[   ] * Timeout! but too early\n" );
        }

    } else {

        iac_log(IAC_DEBUG, "[   ] * Timeout!\n");

    }
}

void
ti_print_node(ti_timer_node_t *n)
{
    if (n) {
        
        printf("timer at %ld:%ld calling %p(\"%s\")\n",
            n->ti_interval.tv_sec, n->ti_interval.tv_usec,
            n->ti_func, n->ti_msg);ti_print_node(n->ti_next);
    }
}

void
ti_dump(void)
{
    ti_print_node(ti_root);
}


void
ti_get_timeout(struct timeval *tv)
{
    struct timeval tv_now;
    if (ti_root) {
        
        gettimeofday(&tv_now, NULL);

        tv->tv_sec = (ti_root->ti_interval.tv_sec - tv_now.tv_sec);
        tv->tv_usec = (ti_root->ti_interval.tv_usec - tv_now.tv_usec);

        if (tv->tv_sec < 0) 
        {
            /*
             * this should actually not be possible
             */
            tv->tv_sec = 0;
        }
        
        if (tv->tv_usec < 0) 
        {
            tv->tv_usec = (1000000 + tv->tv_usec);
        }
    
    } else {
        
        /* FIXME: what to do? dummy values for now */
        tv->tv_sec = 5;
        tv->tv_usec = 0;
    }

    if ( tv->tv_sec > 5 )
    {
        tv->tv_sec = 5;
    }
    
    iac_log(IAC_DEBUG, "[   ] * Calculated timeout %ld s %ld usec\n",
        tv->tv_sec, tv->tv_usec);
}

Generated by  Doxygen 1.6.0   Back to index