From 4f0a5e7572a4257894b4bfede42c26d65152609e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 13 Aug 2005 21:25:09 +0000 Subject: * strip glib from avahi-core * implement glib memory allocator * add new documentation file MALLOC * initialize pseudo-RNG from /dev/urandom in avahi-daemon * remove some gcc 4.0 warnings * beef up watch system with real timeouts * move GCC __attribute__ macros into its own header avahi-common/gccmacro.h * make use of GCC's sentinel attribute where it make sense * add malloc() implementations that abort on OOM and enable them by default git-svn-id: file:///home/lennart/svn/public/avahi/trunk@308 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-core/timeeventq.c | 238 ++++++++++++++++++++++-------------------------- 1 file changed, 109 insertions(+), 129 deletions(-) (limited to 'avahi-core/timeeventq.c') diff --git a/avahi-core/timeeventq.c b/avahi-core/timeeventq.c index 88e1779..b069ffd 100644 --- a/avahi-core/timeeventq.c +++ b/avahi-core/timeeventq.c @@ -23,12 +23,32 @@ #include #endif +#include +#include + #include -#include "timeeventq.h" +#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 { + AvahiPoll *poll_api; + AvahiPrioQueue *prioq; +}; + +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,198 +58,158 @@ 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); - - g_source_get_current_time(source, >v); - tv->tv_sec = gtv.tv_sec; - tv->tv_usec = gtv.tv_usec; -} - -static gboolean prepare_func(GSource *source, gint *timeout) { - AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source; - 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; - } +static void expiration_event(AvahiPoll *poll_api, void *userdata); - *timeout = (gint) (avahi_timeval_diff(&e->expiry, &now)/1000); +static void update_wakeup(AvahiTimeEventQueue *q) { + assert(q); - /* Wait at least 1 msec */ - if (*timeout <= 0) - *timeout = 1; - - return FALSE; + if (q->prioq->root) { + AvahiTimeEvent *e = q->prioq->root->data; + q->poll_api->set_wakeup(q->poll_api, &e->expiry, expiration_event, q); + } else + q->poll_api->set_wakeup(q->poll_api, NULL, NULL, NULL); } -static gboolean check_func(GSource *source) { - AvahiTimeEventQueue *q = (AvahiTimeEventQueue*) source; - AvahiTimeEvent *e; +void expiration_event(AvahiPoll *poll_api, void *userdata) { struct timeval now; + AvahiTimeEventQueue *q = userdata; + AvahiTimeEvent *e; - g_assert(source); - - if (!q->prioq->root) - return FALSE; - - e = q->prioq->root->data; - g_assert(e); - - source_get_timeval(source, &now); + gettimeofday(&now, NULL); - 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 = avahi_time_event_queue_root(q))) { - g_assert(source); + /* Check if expired */ + if (avahi_timeval_compare(&now, &e->expiry) >= 0) { - source_get_timeval(source, &now); + /* Make sure to move the entry away from the front */ + e->last_run = now; + avahi_prio_queue_shuffle(q->prioq, e->node); - while (q->prioq->root) { - AvahiTimeEvent *e = q->prioq->root->data; - - /* Not yet expired */ - if (avahi_timeval_compare(&now, &e->expiry) < 0) - break; - - /* 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); + /* Run it */ + assert(e->callback); + e->callback(e, e->userdata); + } } - return TRUE; + update_wakeup(q); } static void fix_expiry_time(AvahiTimeEvent *e) { struct timeval now; - g_assert(e); + assert(e); - source_get_timeval(&e->queue->source, &now); + 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(AvahiPoll *poll_api) { AvahiTimeEventQueue *q; - static GSourceFuncs source_funcs = { - prepare_func, - check_func, - dispatch_func, - NULL, - NULL, - NULL - }; + if (!(q = avahi_new(AvahiTimeEventQueue, 1))) { + avahi_log_error(__FILE__": Out of memory"); + goto oom; + } - q = (AvahiTimeEventQueue*) g_source_new(&source_funcs, sizeof(AvahiTimeEventQueue)); - q->prioq = avahi_prio_queue_new(compare); + if (!(q->prioq = avahi_prio_queue_new(compare))) + goto oom; - g_source_set_priority((GSource*) q, priority); - - g_source_attach(&q->source, context); - + q->poll_api = poll_api; return q; + +oom: + + if (q) + avahi_free(q); + + return NULL; } void avahi_time_event_queue_free(AvahiTimeEventQueue *q) { - g_assert(q); + assert(q); while (q->prioq->root) - avahi_time_event_queue_remove(q, q->prioq->root->data); + avahi_time_event_free(q->prioq->root->data); avahi_prio_queue_free(q->prioq); - g_source_destroy(&q->source); - g_source_unref(&q->source); + 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); + assert(q); + assert(callback); + assert(userdata); - e = g_new(AvahiTimeEvent, 1); + 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_wakeup(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_wakeup(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(q->prioq, e->node); + avahi_prio_queue_shuffle(e->queue->prioq, e->node); + + update_wakeup(e->queue); } AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q) { - g_assert(q); + assert(q); return q->prioq->root ? q->prioq->root->data : NULL; } AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e) { - g_assert(e); + assert(e); return e->node->next->data; } -- cgit