+ if (!(t = avahi_new(AvahiTimeout, 1)))
+ return NULL;
+
+ t->glib_poll = g;
+ t->dead = FALSE;
+
+ if ((t->enabled = !!tv))
+ t->expiry = *tv;
+
+ t->callback = callback;
+ t->userdata = userdata;
+
+ AVAHI_LLIST_PREPEND(AvahiTimeout, timeouts, g->timeouts, t);
+
+ return t;
+}
+
+static void timeout_update(AvahiTimeout *t, const struct timeval *tv) {
+ assert(t);
+ assert(!t->dead);
+
+ if ((t->enabled = !!tv))
+ t->expiry = *tv;
+}
+
+static void timeout_free(AvahiTimeout *t) {
+ assert(t);
+ assert(!t->dead);
+
+ t->dead = TRUE;
+ t->glib_poll->timeout_req_cleanup = TRUE;
+}
+
+static void destroy_timeout(AvahiTimeout *t) {
+ assert(t);
+
+ AVAHI_LLIST_REMOVE(AvahiTimeout, timeouts, t->glib_poll->timeouts, t);
+ avahi_free(t);
+}
+
+static void cleanup_timeouts(AvahiGLibPoll *g, int all) {
+ AvahiTimeout *t, *next;
+ assert(g);
+
+ for (t = g->timeouts; t; t = next) {
+ next = t->timeouts_next;
+
+ if (all || t->dead)
+ destroy_timeout(t);
+ }
+
+ g->timeout_req_cleanup = FALSE;
+}
+
+static AvahiTimeout* find_next_timeout(AvahiGLibPoll *g) {
+ AvahiTimeout *t, *n = NULL;
+ assert(g);
+
+ for (t = g->timeouts; t; t = t->timeouts_next) {
+
+ if (t->dead || !t->enabled)
+ continue;
+
+ if (!n || avahi_timeval_compare(&t->expiry, &n->expiry) < 0)
+ n = t;
+ }
+
+ return n;
+}
+
+static void start_timeout_callback(AvahiTimeout *t) {
+ assert(t);
+ assert(!t->dead);
+ assert(t->enabled);
+
+ t->enabled = 0;
+ t->callback(t, t->userdata);