1 /* $OpenBSD: timer.c,v 1.19 2020/12/11 12:00:01 claudio Exp $ */ 2 3 /* 4 * Copyright (c) 2003-2007 Henning Brauer <henning@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <stdlib.h> 21 22 #include "bgpd.h" 23 #include "session.h" 24 #include "log.h" 25 26 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 27 28 time_t 29 getmonotime(void) 30 { 31 struct timespec ts; 32 33 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 34 fatal("clock_gettime"); 35 36 return (ts.tv_sec); 37 } 38 39 struct timer * 40 timer_get(struct timer_head *th, enum Timer timer) 41 { 42 struct timer *t; 43 44 TAILQ_FOREACH(t, th, entry) 45 if (t->type == timer) 46 break; 47 48 return (t); 49 } 50 51 struct timer * 52 timer_nextisdue(struct timer_head *th, time_t now) 53 { 54 struct timer *t; 55 56 t = TAILQ_FIRST(th); 57 if (t != NULL && t->val > 0 && t->val <= now) 58 return (t); 59 return (NULL); 60 } 61 62 time_t 63 timer_nextduein(struct timer_head *th, time_t now) 64 { 65 struct timer *t; 66 67 if ((t = TAILQ_FIRST(th)) != NULL && t->val > 0) 68 return (MAXIMUM(t->val - now, 0)); 69 return (-1); 70 } 71 72 int 73 timer_running(struct timer_head *th, enum Timer timer, time_t *left) 74 { 75 struct timer *t = timer_get(th, timer); 76 77 if (t != NULL && t->val > 0) { 78 if (left != NULL) 79 *left = t->val - getmonotime(); 80 return (1); 81 } 82 return (0); 83 } 84 85 void 86 timer_set(struct timer_head *th, enum Timer timer, u_int offset) 87 { 88 struct timer *t = timer_get(th, timer); 89 struct timer *next; 90 91 if (t == NULL) { /* have to create */ 92 if ((t = malloc(sizeof(*t))) == NULL) 93 fatal("timer_set"); 94 t->type = timer; 95 } else { 96 if (t->val == getmonotime() + (time_t)offset) 97 return; 98 TAILQ_REMOVE(th, t, entry); 99 } 100 101 t->val = getmonotime() + offset; 102 103 TAILQ_FOREACH(next, th, entry) 104 if (next->val == 0 || next->val > t->val) 105 break; 106 if (next != NULL) 107 TAILQ_INSERT_BEFORE(next, t, entry); 108 else 109 TAILQ_INSERT_TAIL(th, t, entry); 110 } 111 112 void 113 timer_stop(struct timer_head *th, enum Timer timer) 114 { 115 struct timer *t = timer_get(th, timer); 116 117 if (t != NULL) { 118 t->val = 0; 119 TAILQ_REMOVE(th, t, entry); 120 TAILQ_INSERT_TAIL(th, t, entry); 121 } 122 } 123 124 void 125 timer_remove(struct timer_head *th, enum Timer timer) 126 { 127 struct timer *t = timer_get(th, timer); 128 129 if (t != NULL) { 130 TAILQ_REMOVE(th, t, entry); 131 free(t); 132 } 133 } 134 135 void 136 timer_remove_all(struct timer_head *th) 137 { 138 struct timer *t; 139 140 while ((t = TAILQ_FIRST(th)) != NULL) { 141 TAILQ_REMOVE(th, t, entry); 142 free(t); 143 } 144 } 145