summaryrefslogtreecommitdiffstats
path: root/avahi-glib
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
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')
-rw-r--r--avahi-glib/glib-watch-test.c16
-rw-r--r--avahi-glib/glib-watch.c195
-rw-r--r--avahi-glib/glib-watch.h6
3 files changed, 150 insertions, 67 deletions
diff --git a/avahi-glib/glib-watch-test.c b/avahi-glib/glib-watch-test.c
index 17b334d..73114d1 100644
--- a/avahi-glib/glib-watch-test.c
+++ b/avahi-glib/glib-watch-test.c
@@ -52,7 +52,7 @@ static void callback(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdat
}
}
-static void wakeup(AvahiPoll *_api, void *userdata) {
+static void wakeup(AvahiTimeout *t, void *userdata) {
struct timeval tv;
static int i = 0;
@@ -62,26 +62,28 @@ static void wakeup(AvahiPoll *_api, void *userdata) {
g_main_loop_quit(loop);
avahi_elapse_time(&tv, 1000, 0);
- api->set_wakeup(api, &tv, wakeup, NULL);
+ api->timeout_update(t, &tv);
}
int main(int argc, char *argv[]) {
- AvahiGLibPoll *s;
+ AvahiGLibPoll *g;
struct timeval tv;
- s = avahi_glib_poll_new(NULL);
- assert(s);
+ g = avahi_glib_poll_new(NULL, G_PRIORITY_DEFAULT);
+ assert(g);
- api = avahi_glib_poll_get(s);
+ api = avahi_glib_poll_get(g);
api->watch_new(api, 0, AVAHI_WATCH_IN, callback, NULL);
avahi_elapse_time(&tv, 1000, 0);
- api->set_wakeup(api, &tv, wakeup, NULL);
+ api->timeout_new(api, &tv, wakeup, NULL);
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
+
+ avahi_glib_poll_free(g);
return 0;
}
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) {
diff --git a/avahi-glib/glib-watch.h b/avahi-glib/glib-watch.h
index 4fa8a3b..0833bdc 100644
--- a/avahi-glib/glib-watch.h
+++ b/avahi-glib/glib-watch.h
@@ -33,14 +33,14 @@
AVAHI_C_DECL_BEGIN
#endif
-/** GLib main loop adapter */
+/** GLib main loop adapter. You can safely cast this into a GSource */
typedef struct AvahiGLibPoll AvahiGLibPoll;
/** Create a new GLib main loop adapter attached to the specified
context. If context is NULL, the default main loop context is
used. You can attach as many AvahiGLibPoll objects to the same context
- as you want. */
-AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context);
+ as you want. priority takes on of GLib's G_PRIORITY constants. */
+AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, gint priority);
/** Free GLib main loop adapter */
void avahi_glib_poll_free(AvahiGLibPoll *g);