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