From bbd18ba47ee721461a867e5183ef5dd62264ebfb Mon Sep 17 00:00:00 2001 From: Kevin Easton Date: Wed, 20 Sep 2017 23:07:52 +1000 Subject: [PATCH] Introduce time_offset() helper and replace open-coded versions in timer.c This function takes a struct timeval and offsets it by a (potentially fractional) number of seconds, given as a 'double'. --- include/ircaux.h | 1 + source/ircaux.c | 20 +++++++++++++ source/timer.c | 76 +++++++++++++++++------------------------------- 3 files changed, 47 insertions(+), 50 deletions(-) diff --git a/include/ircaux.h b/include/ircaux.h index d201612..9793bcd 100644 --- a/include/ircaux.h +++ b/include/ircaux.h @@ -74,6 +74,7 @@ double BX_time_diff (struct timeval, struct timeval); double time_since(const struct timeval *tv_from); double time_until(const struct timeval *tv_to); int time_cmp(const struct timeval *a, const struct timeval *b); +struct timeval *time_offset(struct timeval *tv, double offset); char * BX_plural (int); int BX_time_to_next_minute (void); char * BX_remove_trailing_spaces (char *); diff --git a/source/ircaux.c b/source/ircaux.c index 259a0b3..c4efdea 100644 --- a/source/ircaux.c +++ b/source/ircaux.c @@ -1747,6 +1747,26 @@ int time_cmp(const struct timeval *a, const struct timeval *b) return (a->tv_sec > b->tv_sec) - (a->tv_sec < b->tv_sec); } +/* Add an offset, in seconds, to a timeval */ +struct timeval *time_offset(struct timeval *tv, double offset) +{ + time_t seconds = offset; /* Discards fractional part */ + + offset -= seconds; + if (offset < 0.0) + { + /* This ensures we never make tv_usec go negative, since it might be unsigned. */ + offset += 1.0; + seconds -= 1; + } + tv->tv_usec += offset * 1000000.0; + seconds += tv->tv_usec / 1000000; + tv->tv_usec %= 1000000; + tv->tv_sec += seconds; + + return tv; +} + int BX_time_to_next_minute (void) { time_t now = time(NULL); diff --git a/source/timer.c b/source/timer.c index a9248c6..c185322 100644 --- a/source/timer.c +++ b/source/timer.c @@ -164,18 +164,18 @@ static char *current_exec_timer = empty_string; extern void ExecuteTimers (void) { TimerList *current; - static int parsingtimer = 0; + static int parsingtimer = 0; int old_from_server = from_server; struct timeval now1; - - /* We do NOT want to parse timers while waiting - * cause it gets icky recursive - */ - if (!PendingTimers || parsingtimer) - return; + + /* We do NOT want to parse timers while waiting + * cause it gets icky recursive + */ + if (!PendingTimers || parsingtimer) + return; get_time(&now1); - - parsingtimer = 1; + + parsingtimer = 1; while (PendingTimers && time_cmp(&now1, &PendingTimers->time) >= 0) { int old_refnum = current_window->refnum; @@ -195,7 +195,7 @@ extern void ExecuteTimers (void) from_server = get_window_server(0); else from_server = -1; - + /* * If a callback function was registered, then * we use it. If no callback function was registered, @@ -218,37 +218,26 @@ extern void ExecuteTimers (void) { case 0: case 1: - { - /* callback cleans up command */ - if (!current->callback) - new_free(¤t->command); - new_free(¤t->subargs); - new_free(¤t->whom); - new_free(¤t); - break; - } + { + /* callback cleans up command */ + if (!current->callback) + new_free(¤t->command); + new_free(¤t->subargs); + new_free(¤t->whom); + new_free(¤t); + break; + } default: current->events--; case -1: - { -#if 1 - double milli, seconds; - milli = current->interval * 1000 * 1000 + current->time.tv_usec; - seconds = current->time.tv_sec + (milli / 1000000); - milli = ((unsigned long)current) % 1000000; - current->time.tv_sec = seconds; - current->time.tv_usec = milli; -#else - current->time.tv_usec += (current->interval * 1000); - current->time.tv_sec += (current->time.tv_usec / 1000000); - current->time.tv_usec %= 1000000; -#endif - schedule_timer(current); - break; - } + { + time_offset(¤t->time, current->interval); + schedule_timer(current); + break; + } } } - parsingtimer = 0; + parsingtimer = 0; } /* @@ -464,24 +453,11 @@ char *BX_add_timer(int update, char *refnum_want, double when, long events, int { TimerList *ntimer, *otimer = NULL; char refnum_got[REFNUM_MAX+1] = ""; - double seconds = 0.0, milli = 0.0; -extern double fmod(double, double); ntimer = (TimerList *) new_malloc(sizeof(TimerList)); get_time(&ntimer->time); -#if 1 - milli = when * 1000 + ntimer->time.tv_usec; - seconds = ntimer->time.tv_sec + (milli / 1000000); - - milli = ((unsigned long)milli) % 1000000; - ntimer->time.tv_sec = seconds; - ntimer->time.tv_usec = milli; -#else - ntimer->time.tv_usec += (unsigned long)when; - ntimer->time.tv_sec += ((when + ntimer->time.tv_usec) / 1000); - ntimer->time.tv_usec %= 1000; -#endif + time_offset(&ntimer->time, when / 1000.0); ntimer->interval = when / 1000; ntimer->events = events;