Initial import (again)
[srvx.git] / src / timeq.c
1 /* timeq.c - time-based event queue
2  * Copyright 2000-2004 srvx Development Team
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.  Important limitations are
8  * listed in the COPYING file that accompanies this software.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, email srvx-maintainers@srvx.net.
17  */
18
19 #include "common.h"
20 #include "heap.h"
21 #include "timeq.h"
22
23 heap_t timeq;
24
25 struct timeq_entry {
26     timeq_func func;
27     void *data;
28 };
29
30 static void
31 timeq_cleanup(void)
32 {
33     timeq_del(0, 0, 0, TIMEQ_IGNORE_WHEN|TIMEQ_IGNORE_FUNC|TIMEQ_IGNORE_DATA);
34     heap_delete(timeq);
35 }
36
37 void
38 timeq_init(void)
39 {
40     timeq = heap_new(int_comparator);
41     reg_exit_func(timeq_cleanup);
42 }
43
44 time_t
45 timeq_next(void)
46 {
47     void *time;
48     heap_peek(timeq, &time, 0);
49     return (time_t)time;
50 }
51
52 void
53 timeq_add(time_t when, timeq_func func, void *data)
54 {
55     struct timeq_entry *ent;
56     void *w;
57     ent = malloc(sizeof(struct timeq_entry));
58     ent->func = func;
59     ent->data = data;
60     w = (void*)when;
61     heap_insert(timeq, w, ent);
62 }
63
64 struct timeq_extra {
65     time_t when;
66     timeq_func func;
67     void *data;
68     int mask;
69 };
70
71 static int
72 timeq_del_matching(void *key, void *data, void *extra)
73 {
74     struct timeq_entry *a = data;
75     struct timeq_extra *b = extra;
76     if (((b->mask & TIMEQ_IGNORE_WHEN) || ((time_t)key == b->when))
77         && ((b->mask & TIMEQ_IGNORE_FUNC) || (a->func == b->func))
78         && ((b->mask & TIMEQ_IGNORE_DATA) || (a->data == b->data))) {
79         free(data);
80         return 1;
81     } else {
82         return 0;
83     }
84 }
85
86 void
87 timeq_del(time_t when, timeq_func func, void *data, int mask)
88 {
89     struct timeq_extra extra;
90     extra.when = when;
91     extra.func = func;
92     extra.data = data;
93     extra.mask = mask;
94     heap_remove_pred(timeq, timeq_del_matching, &extra);
95 }
96
97 unsigned int
98 timeq_size(void)
99 {
100     return heap_size(timeq);
101 }
102
103 void
104 timeq_run(void)
105 {
106     void *k, *d;
107     struct timeq_entry *ent;
108     while (heap_size(timeq) > 0) {
109         heap_peek(timeq, &k, &d);
110         if ((time_t)k > now)
111             break;
112         ent = d;
113         heap_pop(timeq);
114         ent->func(ent->data);
115         free(ent);
116     }
117 }