X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Ftimeeventq.c;h=2799bf242602171d69b96b878e61bb4f8de4d05b;hb=9c0f9c65093cfa53d45f9b68782321eb8063a032;hp=fbdb6d59928660466a4c82c727c92c926b799857;hpb=e63a65b3955b173a3e8d6b78c6377a518a9922d6;p=catta diff --git a/avahi-core/timeeventq.c b/avahi-core/timeeventq.c index fbdb6d5..2799bf2 100644 --- a/avahi-core/timeeventq.c +++ b/avahi-core/timeeventq.c @@ -1,18 +1,16 @@ -/* $Id$ */ - /*** This file is part of avahi. - + avahi is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. - + avahi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - + You should have received a copy of the GNU Lesser General Public License along with avahi; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 @@ -23,12 +21,33 @@ #include #endif -#include "timeeventq.h" -#include "util.h" +#include +#include + +#include +#include -static gint compare(gconstpointer _a, gconstpointer _b) { +#include "timeeventq.h" +#include "log.h" + +struct AvahiTimeEvent { + AvahiTimeEventQueue *queue; + AvahiPrioQueueNode *node; + struct timeval expiry; + struct timeval last_run; + AvahiTimeEventCallback callback; + void* userdata; +}; + +struct AvahiTimeEventQueue { + const AvahiPoll *poll_api; + AvahiPrioQueue *prioq; + AvahiTimeout *timeout; +}; + +static int compare(const void* _a, const void* _b) { const AvahiTimeEvent *a = _a, *b = _b; - gint ret; + int ret; if ((ret = avahi_timeval_compare(&a->expiry, &b->expiry)) != 0) return ret; @@ -38,200 +57,169 @@ static gint compare(gconstpointer _a, gconstpointer _b) { return avahi_timeval_compare(&a->last_run, &b->last_run); } -static void source_get_timeval(GSource *source, struct timeval *tv) { - GTimeVal gtv; - - g_assert(source); - g_assert(tv); +static AvahiTimeEvent* time_event_queue_root(AvahiTimeEventQueue *q) { + assert(q); - g_source_get_current_time(source, >v); - tv->tv_sec = gtv.tv_sec; - tv->tv_usec = gtv.tv_usec; + return q->prioq->root ? q->prioq->root->data : NULL; } -static gboolean prepare_func(GSource *source, gint *timeout) { - AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source; +static void update_timeout(AvahiTimeEventQueue *q) { AvahiTimeEvent *e; - struct timeval now; - - g_assert(source); - g_assert(timeout); - - if (!q->prioq->root) { - *timeout = -1; - return FALSE; - } - - e = q->prioq->root->data; - g_assert(e); - - source_get_timeval(source, &now); - - if (avahi_timeval_compare(&now, &e->expiry) >= 0 && /* Time elapsed */ - avahi_timeval_compare(&now, &e->last_run) != 0 /* Not yet run */) { - *timeout = -1; - return TRUE; - } + assert(q); - *timeout = (gint) (avahi_timeval_diff(&e->expiry, &now)/1000); - - /* Wait at least 1 msec */ - if (*timeout <= 0) - *timeout = 1; - - return FALSE; + if ((e = time_event_queue_root(q))) + q->poll_api->timeout_update(q->timeout, &e->expiry); + else + q->poll_api->timeout_update(q->timeout, NULL); } -static gboolean check_func(GSource *source) { - AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source; +static void expiration_event(AVAHI_GCC_UNUSED AvahiTimeout *timeout, void *userdata) { + AvahiTimeEventQueue *q = userdata; AvahiTimeEvent *e; - struct timeval now; - - g_assert(source); - - if (!q->prioq->root) - return FALSE; - e = q->prioq->root->data; - g_assert(e); - - source_get_timeval(source, &now); - - return - avahi_timeval_compare(&now, &e->expiry) >= 0 && /* Time elapsed */ - avahi_timeval_compare(&now, &e->last_run) != 0; /* Not yet run */ -} - -static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer user_data) { - AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source; - struct timeval now; + if ((e = time_event_queue_root(q))) { + struct timeval now; - g_assert(source); + gettimeofday(&now, NULL); - source_get_timeval(source, &now); + /* Check if expired */ + if (avahi_timeval_compare(&now, &e->expiry) >= 0) { - while (q->prioq->root) { - AvahiTimeEvent *e = q->prioq->root->data; + /* Make sure to move the entry away from the front */ + e->last_run = now; + avahi_prio_queue_shuffle(q->prioq, e->node); - /* Not yet expired */ - if (avahi_timeval_compare(&now, &e->expiry) < 0) - break; + /* Run it */ + assert(e->callback); + e->callback(e, e->userdata); - /* Already ran */ - if (avahi_timeval_compare(&now, &e->last_run) == 0) - break; - - /* Make sure to move the entry away from the front */ - e->last_run = now; - avahi_prio_queue_shuffle(q->prioq, e->node); - - /* Run it */ - g_assert(e->callback); - e->callback(e, e->userdata); + update_timeout(q); + return; + } } - return TRUE; + avahi_log_debug(__FILE__": Strange, expiration_event() called, but nothing really happened."); + update_timeout(q); } static void fix_expiry_time(AvahiTimeEvent *e) { struct timeval now; - g_assert(e); + assert(e); - source_get_timeval(&e->queue->source, &now); + return; /*** DO WE REALLY NEED THIS? ***/ + + gettimeofday(&now, NULL); if (avahi_timeval_compare(&now, &e->expiry) > 0) e->expiry = now; - } -AvahiTimeEventQueue* avahi_time_event_queue_new(GMainContext *context, gint priority) { +AvahiTimeEventQueue* avahi_time_event_queue_new(const AvahiPoll *poll_api) { AvahiTimeEventQueue *q; - static GSourceFuncs source_funcs = { - prepare_func, - check_func, - dispatch_func, - NULL, - NULL, - NULL - }; - - q = (AvahiTimeEventQueue*) g_source_new(&source_funcs, sizeof(AvahiTimeEventQueue)); - q->prioq = avahi_prio_queue_new(compare); - - g_source_set_priority((GSource*) q, priority); - - g_source_attach(&q->source, context); - + if (!(q = avahi_new(AvahiTimeEventQueue, 1))) { + avahi_log_error(__FILE__": Out of memory"); + goto oom; + } + + q->poll_api = poll_api; + + if (!(q->prioq = avahi_prio_queue_new(compare))) + goto oom; + + if (!(q->timeout = poll_api->timeout_new(poll_api, NULL, expiration_event, q))) + goto oom; + return q; + +oom: + + if (q) { + avahi_free(q); + + if (q->prioq) + avahi_prio_queue_free(q->prioq); + } + + return NULL; } void avahi_time_event_queue_free(AvahiTimeEventQueue *q) { - g_assert(q); + AvahiTimeEvent *e; + + assert(q); - while (q->prioq->root) - avahi_time_event_queue_remove(q, q->prioq->root->data); + while ((e = time_event_queue_root(q))) + avahi_time_event_free(e); avahi_prio_queue_free(q->prioq); - g_source_destroy(&q->source); - g_source_unref(&q->source); + q->poll_api->timeout_free(q->timeout); + + avahi_free(q); } -AvahiTimeEvent* avahi_time_event_queue_add(AvahiTimeEventQueue *q, const struct timeval *timeval, AvahiTimeEventCallback callback, gpointer userdata) { +AvahiTimeEvent* avahi_time_event_new( + AvahiTimeEventQueue *q, + const struct timeval *timeval, + AvahiTimeEventCallback callback, + void* userdata) { + AvahiTimeEvent *e; - - g_assert(q); - g_assert(timeval); - g_assert(callback); - g_assert(userdata); - e = g_new(AvahiTimeEvent, 1); + assert(q); + assert(callback); + assert(userdata); + + if (!(e = avahi_new(AvahiTimeEvent, 1))) { + avahi_log_error(__FILE__": Out of memory"); + return NULL; /* OOM */ + } + e->queue = q; e->callback = callback; e->userdata = userdata; - e->expiry = *timeval; + if (timeval) + e->expiry = *timeval; + else { + e->expiry.tv_sec = 0; + e->expiry.tv_usec = 0; + } + fix_expiry_time(e); - + e->last_run.tv_sec = 0; e->last_run.tv_usec = 0; - e->node = avahi_prio_queue_put(q->prioq, e); - + if (!(e->node = avahi_prio_queue_put(q->prioq, e))) { + avahi_free(e); + return NULL; + } + + update_timeout(q); return e; } -void avahi_time_event_queue_remove(AvahiTimeEventQueue *q, AvahiTimeEvent *e) { - g_assert(q); - g_assert(e); - g_assert(e->queue == q); +void avahi_time_event_free(AvahiTimeEvent *e) { + AvahiTimeEventQueue *q; + assert(e); + + q = e->queue; avahi_prio_queue_remove(q->prioq, e->node); - g_free(e); + avahi_free(e); + + update_timeout(q); } -void avahi_time_event_queue_update(AvahiTimeEventQueue *q, AvahiTimeEvent *e, const struct timeval *timeval) { - g_assert(q); - g_assert(e); - g_assert(e->queue == q); - g_assert(timeval); +void avahi_time_event_update(AvahiTimeEvent *e, const struct timeval *timeval) { + assert(e); + assert(timeval); e->expiry = *timeval; fix_expiry_time(e); + avahi_prio_queue_shuffle(e->queue->prioq, e->node); - avahi_prio_queue_shuffle(q->prioq, e->node); + update_timeout(e->queue); } -AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q) { - g_assert(q); - - return q->prioq->root ? q->prioq->root->data : NULL; -} - -AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e) { - g_assert(e); - - return e->node->next->data; -} - -