1 /* $OpenBSD: timer.c,v 1.15 2012/04/12 17:26:09 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/param.h> 20 #include <sys/types.h> 21 #include <stdlib.h> 22 23 #include "bgpd.h" 24 #include "session.h" 25 26 time_t 27 getmonotime(void) 28 { 29 struct timespec ts; 30 31 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) 32 fatal("clock_gettime"); 33 34 return (ts.tv_sec); 35 } 36 37 struct peer_timer * 38 timer_get(struct peer *p, enum Timer timer) 39 { 40 struct peer_timer *pt; 41 42 TAILQ_FOREACH(pt, &p->timers, entry) 43 if (pt->type == timer) 44 break; 45 46 return (pt); 47 } 48 49 struct peer_timer * 50 timer_nextisdue(struct peer *p) 51 { 52 struct peer_timer *pt; 53 54 pt = TAILQ_FIRST(&p->timers); 55 if (pt != NULL && pt->val > 0 && pt->val <= getmonotime()) 56 return (pt); 57 return (NULL); 58 } 59 60 time_t 61 timer_nextduein(struct peer *p) 62 { 63 struct peer_timer *pt; 64 65 if ((pt = TAILQ_FIRST(&p->timers)) != NULL && pt->val > 0) 66 return (MAX(pt->val - getmonotime(), 0)); 67 return (-1); 68 } 69 70 int 71 timer_running(struct peer *p, enum Timer timer, time_t *left) 72 { 73 struct peer_timer *pt = timer_get(p, timer); 74 75 if (pt != NULL && pt->val > 0) { 76 if (left != NULL) 77 *left = pt->val - getmonotime(); 78 return (1); 79 } 80 return (0); 81 } 82 83 void 84 timer_set(struct peer *p, enum Timer timer, u_int offset) 85 { 86 struct peer_timer *t, *pt = timer_get(p, timer); 87 88 if (pt == NULL) { /* have to create */ 89 if ((pt = malloc(sizeof(*pt))) == NULL) 90 fatal("timer_set"); 91 pt->type = timer; 92 } else { 93 if (pt->val == getmonotime() + (time_t)offset) 94 return; 95 TAILQ_REMOVE(&p->timers, pt, entry); 96 } 97 98 pt->val = getmonotime() + offset; 99 100 TAILQ_FOREACH(t, &p->timers, entry) 101 if (t->val == 0 || t->val > pt->val) 102 break; 103 if (t != NULL) 104 TAILQ_INSERT_BEFORE(t, pt, entry); 105 else 106 TAILQ_INSERT_TAIL(&p->timers, pt, entry); 107 } 108 109 void 110 timer_stop(struct peer *p, enum Timer timer) 111 { 112 struct peer_timer *pt = timer_get(p, timer); 113 114 if (pt != NULL) { 115 pt->val = 0; 116 TAILQ_REMOVE(&p->timers, pt, entry); 117 TAILQ_INSERT_TAIL(&p->timers, pt, entry); 118 } 119 } 120 121 void 122 timer_remove(struct peer *p, enum Timer timer) 123 { 124 struct peer_timer *pt = timer_get(p, timer); 125 126 if (pt != NULL) { 127 TAILQ_REMOVE(&p->timers, pt, entry); 128 free(pt); 129 } 130 } 131 132 void 133 timer_remove_all(struct peer *p) 134 { 135 struct peer_timer *pt; 136 137 while ((pt = TAILQ_FIRST(&p->timers)) != NULL) { 138 TAILQ_REMOVE(&p->timers, pt, entry); 139 free(pt); 140 } 141 } 142