diff options
Diffstat (limited to 'trunk/avahi-glib/glib-watch.c')
-rw-r--r-- | trunk/avahi-glib/glib-watch.c | 404 |
1 files changed, 0 insertions, 404 deletions
diff --git a/trunk/avahi-glib/glib-watch.c b/trunk/avahi-glib/glib-watch.c deleted file mode 100644 index f0fd934..0000000 --- a/trunk/avahi-glib/glib-watch.c +++ /dev/null @@ -1,404 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of avahi. - - avahi is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - avahi is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General - Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with avahi; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <avahi-common/llist.h> -#include <avahi-common/malloc.h> -#include <avahi-common/timeval.h> - -#include "glib-watch.h" - -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; - - gboolean timeout_req_cleanup; - gboolean watch_req_cleanup; - - AVAHI_LLIST_HEAD(AvahiWatch, watches); - AVAHI_LLIST_HEAD(AvahiTimeout, timeouts); -}; - -static void destroy_watch(AvahiWatch *w) { - assert(w); - - if (w->pollfd_added) - g_source_remove_poll(&w->glib_poll->source, &w->pollfd); - - AVAHI_LLIST_REMOVE(AvahiWatch, watches, w->glib_poll->watches, w); - - avahi_free(w); -} - -static void cleanup_watches(AvahiGLibPoll *g, int all) { - AvahiWatch *w, *next; - assert(g); - - for (w = g->watches; w; w = next) { - next = w->watches_next; - - if (all || w->dead) - destroy_watch(w); - } - - g->watch_req_cleanup = 0; -} - -static gushort map_events_to_glib(AvahiWatchEvent events) { - return - (events & AVAHI_WATCH_IN ? G_IO_IN : 0) | - (events & AVAHI_WATCH_OUT ? G_IO_OUT : 0) | - (events & AVAHI_WATCH_ERR ? G_IO_ERR : 0) | - (events & AVAHI_WATCH_HUP ? G_IO_HUP : 0); -} - -static AvahiWatchEvent map_events_from_glib(gushort events) { - return - (events & G_IO_IN ? AVAHI_WATCH_IN : 0) | - (events & G_IO_OUT ? AVAHI_WATCH_OUT : 0) | - (events & G_IO_ERR ? AVAHI_WATCH_ERR : 0) | - (events & G_IO_HUP ? AVAHI_WATCH_HUP : 0); -} - -static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent events, AvahiWatchCallback callback, void *userdata) { - AvahiWatch *w; - AvahiGLibPoll *g; - - assert(api); - assert(fd >= 0); - assert(callback); - - g = api->userdata; - assert(g); - - if (!(w = avahi_new(AvahiWatch, 1))) - return NULL; - - w->glib_poll = g; - w->pollfd.fd = fd; - w->pollfd.events = map_events_to_glib(events); - w->pollfd.revents = 0; - w->callback = callback; - w->userdata = userdata; - w->dead = FALSE; - - g_source_add_poll(&g->source, &w->pollfd); - w->pollfd_added = TRUE; - - AVAHI_LLIST_PREPEND(AvahiWatch, watches, g->watches, w); - - return w; -} - -static void watch_update(AvahiWatch *w, AvahiWatchEvent events) { - assert(w); - assert(!w->dead); - - w->pollfd.events = map_events_to_glib(events); -} - -static AvahiWatchEvent watch_get_events(AvahiWatch *w) { - assert(w); - assert(!w->dead); - - return map_events_from_glib(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 = FALSE; - } - - w->dead = TRUE; - w->glib_poll->timeout_req_cleanup = TRUE; -} - -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 (!(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); -} - -static gboolean prepare_func(GSource *source, gint *timeout) { - AvahiGLibPoll *g = (AvahiGLibPoll*) source; - AvahiTimeout *next_timeout; - - g_assert(g); - g_assert(timeout); - - if (g->watch_req_cleanup) - cleanup_watches(g, 0); - - if (g->timeout_req_cleanup) - cleanup_timeouts(g, 0); - - if ((next_timeout = find_next_timeout(g))) { - GTimeVal now; - struct timeval tvnow; - AvahiUsec usec; - - g_source_get_current_time(source, &now); - tvnow.tv_sec = now.tv_sec; - tvnow.tv_usec = now.tv_usec; - - usec = avahi_timeval_diff(&next_timeout->expiry, &tvnow); - - if (usec <= 0) { - *timeout = 0; - return TRUE; - } - - *timeout = (gint) (usec / 1000); - } else - *timeout = -1; - - return FALSE; -} - -static gboolean check_func(GSource *source) { - AvahiGLibPoll *g = (AvahiGLibPoll*) source; - AvahiWatch *w; - AvahiTimeout *next_timeout; - - g_assert(g); - - 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(&next_timeout->expiry, &tvnow) <= 0) - return TRUE; - } - - for (w = g->watches; w; w = w->watches_next) - if (w->pollfd.revents > 0) - return TRUE; - - return FALSE; -} - -static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc callback, AVAHI_GCC_UNUSED gpointer userdata) { - AvahiGLibPoll* g = (AvahiGLibPoll*) source; - AvahiWatch *w; - AvahiTimeout *next_timeout; - - g_assert(g); - - 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(&next_timeout->expiry, &tvnow) < 0) { - start_timeout_callback(next_timeout); - return TRUE; - } - } - - for (w = g->watches; w; w = w->watches_next) - if (w->pollfd.revents > 0) { - assert(w->callback); - w->callback(w, w->pollfd.fd, map_events_from_glib(w->pollfd.revents), w->userdata); - w->pollfd.revents = 0; - return TRUE; - } - - return TRUE; -} - -AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, gint priority) { - AvahiGLibPoll *g; - - static GSourceFuncs source_funcs = { - prepare_func, - check_func, - dispatch_func, - NULL, - NULL, - NULL - }; - - g = (AvahiGLibPoll*) g_source_new(&source_funcs, sizeof(AvahiGLibPoll)); - 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.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->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); - g_source_set_can_recurse(&g->source, FALSE); - - return g; -} - -void avahi_glib_poll_free(AvahiGLibPoll *g) { - GSource *s = &g->source; - assert(g); - - cleanup_watches(g, 1); - cleanup_timeouts(g, 1); - - g_main_context_unref(g->context); - g_source_destroy(s); - g_source_unref(s); -} - -const AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g) { - assert(g); - - return &g->api; -} |