4 This file is part of avahi.
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.
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.
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
29 #include <avahi-common/timeval.h>
30 #include <avahi-common/malloc.h>
32 #include "timeeventq.h"
35 struct AvahiTimeEvent {
36 AvahiTimeEventQueue *queue;
37 AvahiPrioQueueNode *node;
38 struct timeval expiry;
39 struct timeval last_run;
40 AvahiTimeEventCallback callback;
44 struct AvahiTimeEventQueue {
45 const AvahiPoll *poll_api;
46 AvahiPrioQueue *prioq;
49 static int compare(const void* _a, const void* _b) {
50 const AvahiTimeEvent *a = _a, *b = _b;
53 if ((ret = avahi_timeval_compare(&a->expiry, &b->expiry)) != 0)
56 /* If both exevents are scheduled for the same time, put the entry
57 * that has been run earlier the last time first. */
58 return avahi_timeval_compare(&a->last_run, &b->last_run);
61 static void expiration_event(AvahiPoll *poll_api, void *userdata);
63 static void update_wakeup(AvahiTimeEventQueue *q) {
67 AvahiTimeEvent *e = q->prioq->root->data;
68 q->poll_api->set_wakeup(q->poll_api, &e->expiry, expiration_event, q);
70 q->poll_api->set_wakeup(q->poll_api, NULL, NULL, NULL);
73 void expiration_event(AvahiPoll *poll_api, void *userdata) {
75 AvahiTimeEventQueue *q = userdata;
78 gettimeofday(&now, NULL);
80 if ((e = avahi_time_event_queue_root(q))) {
82 /* Check if expired */
83 if (avahi_timeval_compare(&now, &e->expiry) >= 0) {
85 /* Make sure to move the entry away from the front */
87 avahi_prio_queue_shuffle(q->prioq, e->node);
91 e->callback(e, e->userdata);
98 static void fix_expiry_time(AvahiTimeEvent *e) {
102 gettimeofday(&now, NULL);
104 if (avahi_timeval_compare(&now, &e->expiry) > 0)
108 AvahiTimeEventQueue* avahi_time_event_queue_new(const AvahiPoll *poll_api) {
109 AvahiTimeEventQueue *q;
111 if (!(q = avahi_new(AvahiTimeEventQueue, 1))) {
112 avahi_log_error(__FILE__": Out of memory");
116 if (!(q->prioq = avahi_prio_queue_new(compare)))
119 q->poll_api = poll_api;
130 void avahi_time_event_queue_free(AvahiTimeEventQueue *q) {
133 while (q->prioq->root)
134 avahi_time_event_free(q->prioq->root->data);
135 avahi_prio_queue_free(q->prioq);
140 AvahiTimeEvent* avahi_time_event_new(
141 AvahiTimeEventQueue *q,
142 const struct timeval *timeval,
143 AvahiTimeEventCallback callback,
152 if (!(e = avahi_new(AvahiTimeEvent, 1))) {
153 avahi_log_error(__FILE__": Out of memory");
154 return NULL; /* OOM */
158 e->callback = callback;
159 e->userdata = userdata;
162 e->expiry = *timeval;
164 e->expiry.tv_sec = 0;
165 e->expiry.tv_usec = 0;
170 e->last_run.tv_sec = 0;
171 e->last_run.tv_usec = 0;
173 if (!(e->node = avahi_prio_queue_put(q->prioq, e))) {
182 void avahi_time_event_free(AvahiTimeEvent *e) {
183 AvahiTimeEventQueue *q;
188 avahi_prio_queue_remove(q->prioq, e->node);
194 void avahi_time_event_update(AvahiTimeEvent *e, const struct timeval *timeval) {
198 e->expiry = *timeval;
200 avahi_prio_queue_shuffle(e->queue->prioq, e->node);
202 update_wakeup(e->queue);
205 AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q) {
208 return q->prioq->root ? q->prioq->root->data : NULL;
211 AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e) {
214 return e->node->next->data;