summaryrefslogtreecommitdiffstats
path: root/avahi-glib/glib-watch.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-08-14 22:11:35 +0000
committerLennart Poettering <lennart@poettering.net>2005-08-14 22:11:35 +0000
commit769c00f228ba0d37217aaf1424dedde390e7a01c (patch)
treee641d94f918a133f59e0eeb8e07109247d4d7aab /avahi-glib/glib-watch.c
parenta4acfaf4f942f702606e660990c873c9ff5b0395 (diff)
* add new priority parameter to avahi_glib_poll_new()
* beef up AvahiPoll a little to contain real timeout events * cleanups in avahi-client * drop glib dependency * port to AvahiPoll system * put some "const"s and "static"s in to make gcc shut up * change all uses of malloc/free to avahi_malloc/avahi_new/avahi_free git-svn-id: file:///home/lennart/svn/public/avahi/trunk@324 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
Diffstat (limited to 'avahi-glib/glib-watch.c')
-rw-r--r--avahi-glib/glib-watch.c195
1 files changed, 138 insertions, 57 deletions
diff --git a/avahi-glib/glib-watch.c b/avahi-glib/glib-watch.c
index f099e5a..e6def46 100644
--- a/avahi-glib/glib-watch.c
+++ b/avahi-glib/glib-watch.c
@@ -31,26 +31,39 @@
struct AvahiWatch {
AvahiGLibPoll *glib_poll;
int dead;
+
GPollFD pollfd;
int pollfd_added;
+
AvahiWatchCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiWatch, watches);
};
+struct AvahiTimeout {
+ AvahiGLibPoll *glib_poll;
+ gboolean dead;
+
+ gboolean enabled;
+ struct timeval expiry;
+
+ AvahiTimeoutCallback callback;
+ void *userdata;
+
+ AVAHI_LLIST_FIELDS(AvahiTimeout, timeouts);
+};
+
struct AvahiGLibPoll {
GSource source;
AvahiPoll api;
GMainContext *context;
- struct timeval wakeup;
- AvahiWakeupCallback wakeup_callback;
- void *wakeup_userdata;
-
- int req_cleanup;
+ gboolean timeout_req_cleanup;
+ gboolean watch_req_cleanup;
- AVAHI_LLIST_HEAD(AvahiWatch, watches);
+ AVAHI_LLIST_HEAD(AvahiWatch, watches);
+ AVAHI_LLIST_HEAD(AvahiTimeout, timeouts);
};
static void destroy_watch(AvahiWatch *w) {
@@ -64,7 +77,7 @@ static void destroy_watch(AvahiWatch *w) {
avahi_free(w);
}
-static void cleanup(AvahiGLibPoll *g, int all) {
+static void cleanup_watches(AvahiGLibPoll *g, int all) {
AvahiWatch *w, *next;
assert(g);
@@ -75,7 +88,7 @@ static void cleanup(AvahiGLibPoll *g, int all) {
destroy_watch(w);
}
- g->req_cleanup = 0;
+ g->watch_req_cleanup = 0;
}
static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) {
@@ -99,13 +112,13 @@ static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event
(event & AVAHI_WATCH_OUT ? G_IO_OUT : 0) |
(event & AVAHI_WATCH_ERR ? G_IO_ERR : 0) |
(event & AVAHI_WATCH_HUP ? G_IO_HUP : 0);
- ;
+ w->pollfd.revents = 0;
w->callback = callback;
w->userdata = userdata;
- w->dead = 0;
+ w->dead = FALSE;
g_source_add_poll(&g->source, &w->pollfd);
- w->pollfd_added = 1;
+ w->pollfd_added = TRUE;
AVAHI_LLIST_PREPEND(AvahiWatch, watches, g->watches, w);
@@ -119,68 +132,129 @@ static void watch_update(AvahiWatch *w, AvahiWatchEvent events) {
w->pollfd.events = events;
}
+static AvahiWatchEvent watch_get_events(AvahiWatch *w) {
+ assert(w);
+ assert(!w->dead);
+
+ return w->pollfd.revents;
+}
+
static void watch_free(AvahiWatch *w) {
assert(w);
assert(!w->dead);
if (w->pollfd_added) {
g_source_remove_poll(&w->glib_poll->source, &w->pollfd);
- w->pollfd_added = 0;
+ w->pollfd_added = TRUE;
}
- w->dead = 1;
- w->glib_poll->req_cleanup = 1;
+ w->dead = TRUE;
+ w->glib_poll->timeout_req_cleanup = TRUE;
}
-static void set_wakeup(const AvahiPoll *api, const struct timeval *tv, AvahiWakeupCallback callback, void *userdata) {
+static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) {
+ AvahiTimeout *t;
AvahiGLibPoll *g;
-
+
assert(api);
+ assert(callback);
+
g = api->userdata;
+ assert(g);
- if (callback) {
- if (tv)
- g->wakeup = *tv;
- else {
- g->wakeup.tv_sec = 0;
- g->wakeup.tv_usec = 0;
- }
-
- g->wakeup_callback = callback;
- g->wakeup_userdata = userdata;
- } else
- g->wakeup_callback = NULL;
+ 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 start_wakeup_callback(AvahiGLibPoll *g) {
- AvahiWakeupCallback callback;
- void *userdata;
+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);
- /* Reset the wakeup functions, but allow changing of the two
- values from the callback function */
+ for (t = g->timeouts; t; t = next) {
+ next = t->timeouts_next;
- callback = g->wakeup_callback;
- userdata = g->wakeup_userdata;
- g->wakeup_callback = NULL;
- g->wakeup_userdata = NULL;
+ if (all || t->dead)
+ destroy_timeout(t);
+ }
- assert(callback);
-
- callback(&g->api, userdata);
+ 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);
}
static gboolean prepare_func(GSource *source, gint *timeout) {
AvahiGLibPoll *g = (AvahiGLibPoll*) source;
+ AvahiTimeout *next_timeout;
g_assert(g);
g_assert(timeout);
- if (g->req_cleanup)
- cleanup(g, 0);
+ if (g->watch_req_cleanup)
+ cleanup_watches(g, 0);
+
+ if (g->timeout_req_cleanup)
+ cleanup_timeouts(g, 0);
- if (g->wakeup_callback) {
+ if ((next_timeout = find_next_timeout(g))) {
GTimeVal now;
struct timeval tvnow;
AvahiUsec usec;
@@ -189,7 +263,7 @@ static gboolean prepare_func(GSource *source, gint *timeout) {
tvnow.tv_sec = now.tv_sec;
tvnow.tv_usec = now.tv_usec;
- usec = avahi_timeval_diff(&g->wakeup, &tvnow);
+ usec = avahi_timeval_diff(&next_timeout->expiry, &tvnow);
if (usec <= 0)
return TRUE;
@@ -203,17 +277,18 @@ static gboolean prepare_func(GSource *source, gint *timeout) {
static gboolean check_func(GSource *source) {
AvahiGLibPoll *g = (AvahiGLibPoll*) source;
AvahiWatch *w;
+ AvahiTimeout *next_timeout;
g_assert(g);
- if (g->wakeup_callback) {
+ if ((next_timeout = find_next_timeout(g))) {
GTimeVal now;
struct timeval tvnow;
g_source_get_current_time(source, &now);
tvnow.tv_sec = now.tv_sec;
tvnow.tv_usec = now.tv_usec;
- if (avahi_timeval_compare(&g->wakeup, &tvnow) < 0)
+ if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) < 0)
return TRUE;
}
@@ -227,18 +302,19 @@ static gboolean check_func(GSource *source) {
static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) {
AvahiGLibPoll* g = (AvahiGLibPoll*) source;
AvahiWatch *w;
+ AvahiTimeout *next_timeout;
g_assert(g);
- if (g->wakeup_callback) {
+ if ((next_timeout = find_next_timeout(g))) {
GTimeVal now;
struct timeval tvnow;
g_source_get_current_time(source, &now);
tvnow.tv_sec = now.tv_sec;
tvnow.tv_usec = now.tv_usec;
- if (avahi_timeval_compare(&g->wakeup, &tvnow) < 0) {
- start_wakeup_callback(g);
+ if (avahi_timeval_compare(&next_timeout->expiry, &tvnow) < 0) {
+ start_timeout_callback(next_timeout);
return TRUE;
}
}
@@ -254,7 +330,7 @@ static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer us
return TRUE;
}
-AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context) {
+AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, gint priority) {
AvahiGLibPoll *g;
static GSourceFuncs source_funcs = {
@@ -270,17 +346,24 @@ AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context) {
g_main_context_ref(g->context = context ? context : g_main_context_default());
g->api.userdata = g;
+
g->api.watch_new = watch_new;
g->api.watch_free = watch_free;
g->api.watch_update = watch_update;
- g->api.set_wakeup = set_wakeup;
+ g->api.watch_get_events = watch_get_events;
+
+ g->api.timeout_new = timeout_new;
+ g->api.timeout_free = timeout_free;
+ g->api.timeout_update = timeout_update;
- g->wakeup_callback = NULL;
- g->req_cleanup = 0;
+ g->watch_req_cleanup = FALSE;
+ g->timeout_req_cleanup = FALSE;
AVAHI_LLIST_HEAD_INIT(AvahiWatch, g->watches);
+ AVAHI_LLIST_HEAD_INIT(AvahiTimeout, g->timeouts);
g_source_attach(&g->source, g->context);
+ g_source_set_priority(&g->source, priority);
return g;
}
@@ -289,14 +372,12 @@ void avahi_glib_poll_free(AvahiGLibPoll *g) {
GSource *s = &g->source;
assert(g);
-/* g_message("BEFORE"); */
- cleanup(g, 1);
+ cleanup_watches(g, 1);
+ cleanup_timeouts(g, 1);
-/* g_message("MIDDLE"); */
g_main_context_unref(g->context);
g_source_destroy(s);
g_source_unref(s);
-/* g_message("AFTER"); */
}
const AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g) {