1*82fcfa8bSclaudio /* $OpenBSD: timer.c,v 1.19 2020/12/11 12:00:01 claudio Exp $ */
21b5a1903Shenning
31b5a1903Shenning /*
41b5a1903Shenning * Copyright (c) 2003-2007 Henning Brauer <henning@openbsd.org>
51b5a1903Shenning *
61b5a1903Shenning * Permission to use, copy, modify, and distribute this software for any
71b5a1903Shenning * purpose with or without fee is hereby granted, provided that the above
81b5a1903Shenning * copyright notice and this permission notice appear in all copies.
91b5a1903Shenning *
101b5a1903Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111b5a1903Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121b5a1903Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131b5a1903Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141b5a1903Shenning * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151b5a1903Shenning * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161b5a1903Shenning * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171b5a1903Shenning */
181b5a1903Shenning
191b5a1903Shenning #include <sys/types.h>
20c6a99735Shenning #include <stdlib.h>
211b5a1903Shenning
221b5a1903Shenning #include "bgpd.h"
231b5a1903Shenning #include "session.h"
245e3f6f95Sbenno #include "log.h"
251b5a1903Shenning
26b9fc9a72Sderaadt #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
27b9fc9a72Sderaadt
28c465b6beShenning time_t
getmonotime(void)29c465b6beShenning getmonotime(void)
30c465b6beShenning {
31c465b6beShenning struct timespec ts;
32c465b6beShenning
33c465b6beShenning if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
34c465b6beShenning fatal("clock_gettime");
35c465b6beShenning
36c465b6beShenning return (ts.tv_sec);
37c465b6beShenning }
38c465b6beShenning
39*82fcfa8bSclaudio struct timer *
timer_get(struct timer_head * th,enum Timer timer)40*82fcfa8bSclaudio timer_get(struct timer_head *th, enum Timer timer)
411b5a1903Shenning {
42*82fcfa8bSclaudio struct timer *t;
431b5a1903Shenning
44*82fcfa8bSclaudio TAILQ_FOREACH(t, th, entry)
45*82fcfa8bSclaudio if (t->type == timer)
46c6a99735Shenning break;
47c6a99735Shenning
48*82fcfa8bSclaudio return (t);
491b5a1903Shenning }
501b5a1903Shenning
51*82fcfa8bSclaudio struct timer *
timer_nextisdue(struct timer_head * th,time_t now)52*82fcfa8bSclaudio timer_nextisdue(struct timer_head *th, time_t now)
53bc5cc2b0Shenning {
54*82fcfa8bSclaudio struct timer *t;
55bc5cc2b0Shenning
56*82fcfa8bSclaudio t = TAILQ_FIRST(th);
57*82fcfa8bSclaudio if (t != NULL && t->val > 0 && t->val <= now)
58*82fcfa8bSclaudio return (t);
59bc5cc2b0Shenning return (NULL);
60bc5cc2b0Shenning }
61bc5cc2b0Shenning
62f540baacShenning time_t
timer_nextduein(struct timer_head * th,time_t now)63*82fcfa8bSclaudio timer_nextduein(struct timer_head *th, time_t now)
64f540baacShenning {
65*82fcfa8bSclaudio struct timer *t;
66f540baacShenning
67*82fcfa8bSclaudio if ((t = TAILQ_FIRST(th)) != NULL && t->val > 0)
68*82fcfa8bSclaudio return (MAXIMUM(t->val - now, 0));
69eb9ba443Shenning return (-1);
70f540baacShenning }
71f540baacShenning
721b5a1903Shenning int
timer_running(struct timer_head * th,enum Timer timer,time_t * left)73*82fcfa8bSclaudio timer_running(struct timer_head *th, enum Timer timer, time_t *left)
741b5a1903Shenning {
75*82fcfa8bSclaudio struct timer *t = timer_get(th, timer);
761b5a1903Shenning
77*82fcfa8bSclaudio if (t != NULL && t->val > 0) {
7891a7e293Shenning if (left != NULL)
79*82fcfa8bSclaudio *left = t->val - getmonotime();
801b5a1903Shenning return (1);
8191a7e293Shenning }
821b5a1903Shenning return (0);
831b5a1903Shenning }
841b5a1903Shenning
851b5a1903Shenning void
timer_set(struct timer_head * th,enum Timer timer,u_int offset)86*82fcfa8bSclaudio timer_set(struct timer_head *th, enum Timer timer, u_int offset)
871b5a1903Shenning {
88*82fcfa8bSclaudio struct timer *t = timer_get(th, timer);
89*82fcfa8bSclaudio struct timer *next;
901b5a1903Shenning
91*82fcfa8bSclaudio if (t == NULL) { /* have to create */
92*82fcfa8bSclaudio if ((t = malloc(sizeof(*t))) == NULL)
93c6a99735Shenning fatal("timer_set");
94*82fcfa8bSclaudio t->type = timer;
95c6a99735Shenning } else {
96*82fcfa8bSclaudio if (t->val == getmonotime() + (time_t)offset)
97ce7307d2Shenning return;
98*82fcfa8bSclaudio TAILQ_REMOVE(th, t, entry);
99c6a99735Shenning }
100c6a99735Shenning
101*82fcfa8bSclaudio t->val = getmonotime() + offset;
102c6a99735Shenning
103*82fcfa8bSclaudio TAILQ_FOREACH(next, th, entry)
104*82fcfa8bSclaudio if (next->val == 0 || next->val > t->val)
105c6a99735Shenning break;
106*82fcfa8bSclaudio if (next != NULL)
107*82fcfa8bSclaudio TAILQ_INSERT_BEFORE(next, t, entry);
108c6a99735Shenning else
109*82fcfa8bSclaudio TAILQ_INSERT_TAIL(th, t, entry);
1101b5a1903Shenning }
1111b5a1903Shenning
1121b5a1903Shenning void
timer_stop(struct timer_head * th,enum Timer timer)113*82fcfa8bSclaudio timer_stop(struct timer_head *th, enum Timer timer)
1141b5a1903Shenning {
115*82fcfa8bSclaudio struct timer *t = timer_get(th, timer);
1161b5a1903Shenning
117*82fcfa8bSclaudio if (t != NULL) {
118*82fcfa8bSclaudio t->val = 0;
119*82fcfa8bSclaudio TAILQ_REMOVE(th, t, entry);
120*82fcfa8bSclaudio TAILQ_INSERT_TAIL(th, t, entry);
121c6a99735Shenning }
122c6a99735Shenning }
123c6a99735Shenning
124c6a99735Shenning void
timer_remove(struct timer_head * th,enum Timer timer)125*82fcfa8bSclaudio timer_remove(struct timer_head *th, enum Timer timer)
126c6a99735Shenning {
127*82fcfa8bSclaudio struct timer *t = timer_get(th, timer);
128c6a99735Shenning
129*82fcfa8bSclaudio if (t != NULL) {
130*82fcfa8bSclaudio TAILQ_REMOVE(th, t, entry);
131*82fcfa8bSclaudio free(t);
132c6a99735Shenning }
133c6a99735Shenning }
134c6a99735Shenning
135c6a99735Shenning void
timer_remove_all(struct timer_head * th)136*82fcfa8bSclaudio timer_remove_all(struct timer_head *th)
137c6a99735Shenning {
138*82fcfa8bSclaudio struct timer *t;
139c6a99735Shenning
140*82fcfa8bSclaudio while ((t = TAILQ_FIRST(th)) != NULL) {
141*82fcfa8bSclaudio TAILQ_REMOVE(th, t, entry);
142*82fcfa8bSclaudio free(t);
143c6a99735Shenning }
1441b5a1903Shenning }
145