]> git.meshlink.io Git - catta/blob - libavahi-core/timeeventq.c
update todo
[catta] / libavahi-core / timeeventq.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "timeeventq.h"
27 #include "util.h"
28
29 static gint compare(gconstpointer _a, gconstpointer _b) {
30     const AvahiTimeEvent *a = _a,  *b = _b;
31
32     return avahi_timeval_compare(&a->expiry, &b->expiry);
33 }
34
35 static gboolean prepare_func(GSource *source, gint *timeout) {
36     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
37     AvahiTimeEvent *e;
38     GTimeVal now;
39
40     g_assert(source);
41     g_assert(timeout);
42
43     if (!q->prioq->root) {
44         *timeout = -1;
45         return FALSE;
46     }
47     
48     e = q->prioq->root->data;
49     g_assert(e);
50
51     g_source_get_current_time(source, &now);
52
53     if (avahi_timeval_compare(&now, &e->expiry) >= 0) {
54         *timeout = -1;
55         return TRUE;
56     }
57
58     *timeout = (gint) (avahi_timeval_diff(&e->expiry, &now)/1000);
59     
60     return FALSE;
61 }
62
63 static gboolean check_func(GSource *source) {
64     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
65     AvahiTimeEvent *e;
66     GTimeVal now;
67
68     g_assert(source);
69
70     if (!q->prioq->root)
71         return FALSE;
72
73     e = q->prioq->root->data;
74     g_assert(e);
75
76     g_source_get_current_time(source, &now);
77     
78     return avahi_timeval_compare(&now, &e->expiry) >= 0;
79 }
80
81 static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer user_data) {
82     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
83     GTimeVal now;
84
85     g_assert(source);
86
87     g_source_get_current_time(source, &now);
88
89     while (q->prioq->root) {
90         AvahiTimeEvent *e = q->prioq->root->data;
91
92         if (avahi_timeval_compare(&now, &e->expiry) < 0)
93             break;
94
95         g_assert(e->callback);
96         e->callback(e, e->userdata);
97     }
98
99     return TRUE;
100 }
101
102 AvahiTimeEventQueue* avahi_time_event_queue_new(GMainContext *context, gint priority) {
103     AvahiTimeEventQueue *q;
104
105     static GSourceFuncs source_funcs = {
106         prepare_func,
107         check_func,
108         dispatch_func,
109         NULL,
110         NULL,
111         NULL
112     };
113
114     q = (AvahiTimeEventQueue*) g_source_new(&source_funcs, sizeof(AvahiTimeEventQueue));
115     q->prioq = avahi_prio_queue_new(compare);
116
117     g_source_set_priority((GSource*) q, priority);
118     
119     g_source_attach(&q->source, context);
120     
121     return q;
122 }
123
124 void avahi_time_event_queue_free(AvahiTimeEventQueue *q) {
125     g_assert(q);
126
127     while (q->prioq->root)
128         avahi_time_event_queue_remove(q, q->prioq->root->data);
129     avahi_prio_queue_free(q->prioq);
130
131     g_source_destroy(&q->source);
132     g_source_unref(&q->source);
133 }
134
135 AvahiTimeEvent* avahi_time_event_queue_add(AvahiTimeEventQueue *q, const GTimeVal *timeval, void (*callback)(AvahiTimeEvent *e, void *userdata), void *userdata) {
136     AvahiTimeEvent *e;
137     
138     g_assert(q);
139     g_assert(timeval);
140     g_assert(callback);
141     g_assert(userdata);
142
143     e = g_new(AvahiTimeEvent, 1);
144     e->queue = q;
145     e->expiry = *timeval;
146     e->callback = callback;
147     e->userdata = userdata;
148
149     e->node = avahi_prio_queue_put(q->prioq, e);
150     
151     return e;
152 }
153
154 void avahi_time_event_queue_remove(AvahiTimeEventQueue *q, AvahiTimeEvent *e) {
155     g_assert(q);
156     g_assert(e);
157     g_assert(e->queue == q);
158
159     avahi_prio_queue_remove(q->prioq, e->node);
160     g_free(e);
161 }
162
163 void avahi_time_event_queue_update(AvahiTimeEventQueue *q, AvahiTimeEvent *e, const GTimeVal *timeval) {
164     g_assert(q);
165     g_assert(e);
166     g_assert(e->queue == q);
167
168     e->expiry = *timeval;
169
170     avahi_prio_queue_shuffle(q->prioq, e->node);
171 }
172
173 AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q) {
174     g_assert(q);
175
176     return q->prioq->root ? q->prioq->root->data : NULL;
177 }
178
179 AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e) {
180     g_assert(e);
181
182     return e->node->next->data;
183 }
184
185