/* * Copyright (C) 1997-2000 SpellCaster Telecommunications Inc. * $Id: timer.h,v 1.5 2004/08/15 20:46:46 bcrl Exp $ * Released under the GNU Public License. See LICENSE file for details. */ #ifndef CTIMER_H #define CTIMER_H #include #include #include #include class TimeVal { public: struct timeval tv; TimeVal() { tv.tv_sec = 0; tv.tv_usec = 0; } TimeVal(unsigned long sec, unsigned long usec) { tv.tv_sec = sec; tv.tv_usec = usec; } long long scalar(void) { return (long long)tv.tv_sec * 1000000LL + tv.tv_usec; } void Set(unsigned long long val) { tv.tv_sec = val / 1000000; tv.tv_usec = val % 1000000; } void Set(const char *str) { unsigned long long val = atoll(str); Set(val); } void Normalize(void) { long long val = scalar(); tv.tv_sec = val / 1000000; tv.tv_usec = val % 1000000; } void AddHsecs(long hsecs) { tv.tv_sec += hsecs / 100; tv.tv_usec += (hsecs % 100) * (1000000 / 100); Normalize(); } void AddSecs(long secs) { tv.tv_sec += secs; } void GetTimeOfDay(void) { gettimeofday(&tv, NULL); } TimeVal operator+(TimeVal r) { TimeVal res; res.tv.tv_sec = tv.tv_sec + r.tv.tv_sec; res.tv.tv_usec = tv.tv_usec + r.tv.tv_usec; res.Normalize(); return res; } TimeVal operator-(TimeVal r) { TimeVal res; res.tv.tv_sec = tv.tv_sec - r.tv.tv_sec; res.tv.tv_usec = tv.tv_usec - r.tv.tv_usec; res.Normalize(); return res; } int operator<(TimeVal r) { r = r - *this; return (r.tv.tv_sec > 0 || r.tv.tv_usec > 0); } int operator<=(TimeVal r) { r = r - *this; return (r.tv.tv_sec >= 0 && r.tv.tv_usec >= 0); } }; extern void timer_run(void); extern struct timeval timer_getdelay(void); class ctrlfd_t; class dfs_object_t; class CTimer { protected: CTimer *next, *prev; CTimer **my_timer_list; TimeVal etv; unsigned set : 1, active : 1; void (*cbf)(void *cbd); void *cbd; public: CTimer(unsigned long hsecs = 0) { set = 0; active = 0; cbf = NULL; cbd = NULL; next = prev = NULL; my_timer_list = NULL; if (hsecs) Start(hsecs); } virtual ~CTimer() { if (next || prev) remove_from_timer_list(); } void insert_into_timer_list(void); void remove_from_timer_list(void); friend void dump_timer_list(int i, CTimer *timer_list); friend void run_timer_list(TimeVal *, CTimer **); friend struct timeval timer_getdelay(void); CTimer(void (*func)(void *), void *data) { CTimer(); SetFunction(func, data); } void Stop(void) { active = 0; remove_from_timer_list(); } void Start(void) { if (set) { active = 1; insert_into_timer_list(); #ifdef DEBUG fprintf(stderr, "Start timer(%p): expires %d.%06d callback: %p(%p)\n", this, etv.tv.tv_sec, etv.tv.tv_usec, cbf, cbd); #endif } } void Start(unsigned long hsecs) { Set(hsecs); Start(); } void SetFunction(void (*func)(void *), void *data) { cbf = func; cbd = data; } void Set(unsigned long hsecs) { set = 1; etv.GetTimeOfDay(); etv.AddHsecs(hsecs); } int IsActive(void) { return active; } virtual void TimerExpired(void); void dump_full_state(ctrlfd_t *cfd); void dfs_restore(dfs_object_t *obj); }; #endif