]> git.meshlink.io Git - catta/blob - libavahi-core/timeeventq.c
autotoolize
[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 #include "timeeventq.h"
23 #include "util.h"
24
25 static gint compare(gconstpointer _a, gconstpointer _b) {
26     const AvahiTimeEvent *a = _a,  *b = _b;
27
28     return avahi_timeval_compare(&a->expiry, &b->expiry);
29 }
30
31 static gboolean prepare_func(GSource *source, gint *timeout) {
32     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
33     AvahiTimeEvent *e;
34     GTimeVal now;
35
36     g_assert(source);
37     g_assert(timeout);
38
39     if (!q->prioq->root) {
40         *timeout = -1;
41         return FALSE;
42     }
43     
44     e = q->prioq->root->data;
45     g_assert(e);
46
47     g_source_get_current_time(source, &now);
48
49     if (avahi_timeval_compare(&now, &e->expiry) >= 0) {
50         *timeout = -1;
51         return TRUE;
52     }
53
54     *timeout = (gint) (avahi_timeval_diff(&e->expiry, &now)/1000);
55     
56     return FALSE;
57 }
58
59 static gboolean check_func(GSource *source) {
60     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
61     AvahiTimeEvent *e;
62     GTimeVal now;
63
64     g_assert(source);
65
66     if (!q->prioq->root)
67         return FALSE;
68
69     e = q->prioq->root->data;
70     g_assert(e);
71
72     g_source_get_current_time(source, &now);
73     
74     return avahi_timeval_compare(&now, &e->expiry) >= 0;
75 }
76
77 static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer user_data) {
78     AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source;
79     GTimeVal now;
80
81     g_assert(source);
82
83     g_source_get_current_time(source, &now);
84
85     while (q->prioq->root) {
86         AvahiTimeEvent *e = q->prioq->root->data;
87
88         if (avahi_timeval_compare(&now, &e->expiry) < 0)
89             break;
90
91         g_assert(e->callback);
92         e->callback(e, e->userdata);
93     }
94
95     return TRUE;
96 }
97
98 AvahiTimeEventQueue* avahi_time_event_queue_new(GMainContext *context, gint priority) {
99     AvahiTimeEventQueue *q;
100
101     static GSourceFuncs source_funcs = {
102         prepare_func,
103         check_func,
104         dispatch_func,
105         NULL,
106         NULL,
107         NULL
108     };
109
110     q = (AvahiTimeEventQueue*) g_source_new(&source_funcs, sizeof(AvahiTimeEventQueue));
111     q->prioq = avahi_prio_queue_new(compare);
112
113     g_source_set_priority((GSource*) q, priority);
114     
115     g_source_attach(&q->source, context);
116     
117     return q;
118 }
119
120 void avahi_time_event_queue_free(AvahiTimeEventQueue *q) {
121     g_assert(q);
122
123     while (q->prioq->root)
124         avahi_time_event_queue_remove(q, q->prioq->root->data);
125     avahi_prio_queue_free(q->prioq);
126
127     g_source_destroy(&q->source);
128     g_source_unref(&q->source);
129 }
130
131 AvahiTimeEvent* avahi_time_event_queue_add(AvahiTimeEventQueue *q, const GTimeVal *timeval, void (*callback)(AvahiTimeEvent *e, void *userdata), void *userdata) {
132     AvahiTimeEvent *e;
133     
134     g_assert(q);
135     g_assert(timeval);
136     g_assert(callback);
137     g_assert(userdata);
138
139     e = g_new(AvahiTimeEvent, 1);
140     e->queue = q;
141     e->expiry = *timeval;
142     e->callback = callback;
143     e->userdata = userdata;
144
145     e->node = avahi_prio_queue_put(q->prioq, e);
146     
147     return e;
148 }
149
150 void avahi_time_event_queue_remove(AvahiTimeEventQueue *q, AvahiTimeEvent *e) {
151     g_assert(q);
152     g_assert(e);
153     g_assert(e->queue == q);
154
155     avahi_prio_queue_remove(q->prioq, e->node);
156     g_free(e);
157 }
158
159 void avahi_time_event_queue_update(AvahiTimeEventQueue *q, AvahiTimeEvent *e, const GTimeVal *timeval) {
160     g_assert(q);
161     g_assert(e);
162     g_assert(e->queue == q);
163
164     e->expiry = *timeval;
165
166     avahi_prio_queue_shuffle(q->prioq, e->node);
167 }
168
169 AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q) {
170     g_assert(q);
171
172     return q->prioq->root ? q->prioq->root->data : NULL;
173 }
174
175 AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e) {
176     g_assert(e);
177
178     return e->node->next->data;
179 }
180
181