X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-glib%2Fglib-watch.c;h=5b60bbc4cfcbe6c5922547bec031f97364bcc09c;hb=468519681b09f00851e1d4dd658b939e4e938cf6;hp=9d804409df23911c1aea33c44f5eb75785a7e1ef;hpb=854f901f491ccda79aee11edc3d59109cb229d28;p=catta diff --git a/avahi-glib/glib-watch.c b/avahi-glib/glib-watch.c index 9d80440..5b60bbc 100644 --- a/avahi-glib/glib-watch.c +++ b/avahi-glib/glib-watch.c @@ -1,18 +1,16 @@ -/* $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 @@ -32,10 +30,10 @@ struct AvahiWatch { AvahiGLibPoll *glib_poll; int dead; - + GPollFD pollfd; int pollfd_added; - + AvahiWatchCallback callback; void *userdata; @@ -51,7 +49,7 @@ struct AvahiTimeout { AvahiTimeoutCallback callback; void *userdata; - + AVAHI_LLIST_FIELDS(AvahiTimeout, timeouts); }; @@ -62,7 +60,7 @@ struct AvahiGLibPoll { gboolean timeout_req_cleanup; gboolean watch_req_cleanup; - + AVAHI_LLIST_HEAD(AvahiWatch, watches); AVAHI_LLIST_HEAD(AvahiTimeout, timeouts); }; @@ -92,10 +90,26 @@ static void cleanup_watches(AvahiGLibPoll *g, int all) { g->watch_req_cleanup = 0; } -static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) { +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); @@ -105,14 +119,10 @@ static AvahiWatch* watch_new(const AvahiPoll *api, int fd, AvahiWatchEvent event if (!(w = avahi_new(AvahiWatch, 1))) return NULL; - + w->glib_poll = g; w->pollfd.fd = fd; - w->pollfd.events = - (event & AVAHI_WATCH_IN ? G_IO_IN : 0) | - (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.events = map_events_to_glib(events); w->pollfd.revents = 0; w->callback = callback; w->userdata = userdata; @@ -130,14 +140,14 @@ static void watch_update(AvahiWatch *w, AvahiWatchEvent events) { assert(w); assert(!w->dead); - w->pollfd.events = events; + w->pollfd.events = map_events_to_glib(events); } static AvahiWatchEvent watch_get_events(AvahiWatch *w) { assert(w); assert(!w->dead); - return w->pollfd.revents; + return map_events_from_glib(w->pollfd.revents); } static void watch_free(AvahiWatch *w) { @@ -146,9 +156,9 @@ static void watch_free(AvahiWatch *w) { if (w->pollfd_added) { g_source_remove_poll(&w->glib_poll->source, &w->pollfd); - w->pollfd_added = TRUE; + w->pollfd_added = FALSE; } - + w->dead = TRUE; w->glib_poll->timeout_req_cleanup = TRUE; } @@ -156,7 +166,7 @@ static void watch_free(AvahiWatch *w) { static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) { AvahiTimeout *t; AvahiGLibPoll *g; - + assert(api); assert(callback); @@ -165,13 +175,13 @@ static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, 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; @@ -183,7 +193,7 @@ static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, static void timeout_update(AvahiTimeout *t, const struct timeval *tv) { assert(t); assert(!t->dead); - + if ((t->enabled = !!tv)) t->expiry = *tv; } @@ -222,10 +232,10 @@ static AvahiTimeout* find_next_timeout(AvahiGLibPoll *g) { 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; } @@ -254,7 +264,7 @@ static gboolean prepare_func(GSource *source, gint *timeout) { if (g->timeout_req_cleanup) cleanup_timeouts(g, 0); - + if ((next_timeout = find_next_timeout(g))) { GTimeVal now; struct timeval tvnow; @@ -263,15 +273,18 @@ static gboolean prepare_func(GSource *source, gint *timeout) { 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) + if (usec <= 0) { + *timeout = 0; return TRUE; + } *timeout = (gint) (usec / 1000); - } - + } else + *timeout = -1; + return FALSE; } @@ -288,15 +301,15 @@ static gboolean check_func(GSource *source) { 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) + + 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; } @@ -304,7 +317,7 @@ static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc call AvahiGLibPoll* g = (AvahiGLibPoll*) source; AvahiWatch *w; AvahiTimeout *next_timeout; - + g_assert(g); if ((next_timeout = find_next_timeout(g))) { @@ -313,17 +326,17 @@ static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc call 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, w->pollfd.revents, w->userdata); + w->callback(w, w->pollfd.fd, map_events_from_glib(w->pollfd.revents), w->userdata); w->pollfd.revents = 0; return TRUE; } @@ -333,7 +346,7 @@ static gboolean dispatch_func(GSource *source, AVAHI_GCC_UNUSED GSourceFunc call AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, gint priority) { AvahiGLibPoll *g; - + static GSourceFuncs source_funcs = { prepare_func, check_func, @@ -347,24 +360,25 @@ AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, gint priority) { 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; }