summaryrefslogtreecommitdiffstats
path: root/avahi-core/timeeventq.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-08-13 21:25:09 +0000
committerLennart Poettering <lennart@poettering.net>2005-08-13 21:25:09 +0000
commit4f0a5e7572a4257894b4bfede42c26d65152609e (patch)
tree21e3d5ee20716739590e5931859a4c2052161395 /avahi-core/timeeventq.c
parentd6d7d3769441b73ffb5b7af34fef823b41e66312 (diff)
* 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
Diffstat (limited to 'avahi-core/timeeventq.c')
-rw-r--r--avahi-core/timeeventq.c238
1 files changed, 109 insertions, 129 deletions
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 <config.h>
#endif
+#include <assert.h>
+#include <stdlib.h>
+
#include <avahi-common/timeval.h>
-#include "timeeventq.h"
+#include <avahi-common/malloc.h>
-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, &gtv);
- 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;
}