From: Lennart Poettering Date: Fri, 12 Aug 2005 19:09:50 +0000 (+0000) Subject: implement new main loop abstraction layer X-Git-Url: http://git.meshlink.io/?p=catta;a=commitdiff_plain;h=5d047523c87ba11aad8c384f7ffde25b4dd746ed implement new main loop abstraction layer git-svn-id: file:///home/lennart/svn/public/avahi/trunk@305 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- diff --git a/Makefile.am b/Makefile.am index 1ce7f76..628a0ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ SUBDIRS = \ initscript \ avahi-dnsconfd \ avahi-utils \ + avahi-glib \ examples \ man @@ -55,4 +56,3 @@ homepage: scp avahi-daemon/*.introspect avahi-daemon/introspect.dtd avahi-daemon/introspect.xsl\ man/*.xml man/xmltoman.dtd man/xmltoman.xsl \ fdo:public_html/ - diff --git a/avahi-common/Makefile.am b/avahi-common/Makefile.am index d91343b..c78e054 100644 --- a/avahi-common/Makefile.am +++ b/avahi-common/Makefile.am @@ -19,10 +19,6 @@ AM_CFLAGS=-I$(top_srcdir) -# GLIB 2.0 -AM_CFLAGS+=$(GLIB20_CFLAGS) -AM_LDADD=$(GLIB20_LIBS) - # This cool debug trap works on i386/gcc only AM_CFLAGS+='-DDEBUG_TRAP=__asm__("int $$3")' @@ -36,6 +32,9 @@ avahi_commoninclude_HEADERS = \ cdecl.h \ defs.h \ malloc.h + watch.h \ + timeval.h \ + simple-watch.h noinst_HEADERS = llist.h @@ -43,11 +42,12 @@ if ENABLE_DBUS noinst_HEADERS += dbus.h endif - noinst_PROGRAMS = \ strlst-test \ domain-test \ - alternative-test + alternative-test \ + timeval-test \ + watch-test lib_LTLIBRARIES = \ libavahi-common.la @@ -58,7 +58,10 @@ libavahi_common_la_SOURCES = \ alternative.c alternative.h \ error.c error.h \ strlst.c strlst.h \ - domain.c domain.h + domain.c domain.h \ + timeval.c timeval.h \ + simple-watch.c simple-watch.h \ + watch.h libavahi_common_la_CFLAGS = $(AM_CFLAGS) libavahi_common_la_LIBADD = $(AM_LDADD) @@ -84,3 +87,19 @@ domain_test_SOURCES = \ domain_test_CFLAGS = $(AM_CFLAGS) domain_test_LDADD = $(AM_LDADD) +watch_test_SOURCES = \ + timeval.c timeval.h \ + simple-watch.c simple-watch.h \ + watch.h \ + malloc.c malloc.h \ + watch-test.c +watch_test_CFLAGS = $(AM_CFLAGS) +watch_test_LDADD = $(AM_LDADD) + +timeval_test_SOURCES = \ + timeval.c timeval.h \ + timeval-test.c +timeval_test_CFLAGS = $(AM_CFLAGS) +timeval_test_LDADD = $(AM_LDADD) + + diff --git a/avahi-common/simple-watch.c b/avahi-common/simple-watch.c new file mode 100644 index 0000000..acc0923 --- /dev/null +++ b/avahi-common/simple-watch.c @@ -0,0 +1,324 @@ +/* $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 +#endif + +#include +#include +#include +#include + +#include +#include + +#include "simple-watch.h" + +struct AvahiWatch { + AvahiSimplePoll *simple_poll; + int dead; + int idx; + struct pollfd pollfd; + AvahiWatchCallback callback; + void *userdata; + + AVAHI_LLIST_FIELDS(AvahiWatch, watches); +}; + +struct AvahiSimplePoll { + AvahiPoll api; + + struct pollfd* pollfds; + int n_pollfds, max_pollfds, rebuild_pollfds; + + struct timeval wakeup; + int use_wakeup; + + int req_cleanup; + + int quit; + + int n_watches; + AVAHI_LLIST_HEAD(AvahiWatch, watches); +}; + +static AvahiWatch* watch_new(AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata) { + AvahiWatch *w; + AvahiSimplePoll *s; + + assert(api); + assert(fd >= 0); + assert(callback); + + s = api->userdata; + assert(s); + + if (!(w = avahi_new(AvahiWatch, 1))) + return NULL; + + w->simple_poll = s; + w->pollfd.fd = fd; + w->pollfd.events = event; + w->callback = callback; + w->userdata = userdata; + w->dead = 0; + + if (s->n_pollfds < s->max_pollfds) { + /* If there's space for this pollfd, go on and allocate it */ + w->idx = s->n_pollfds++; + s->pollfds[w->idx] = w->pollfd; + + } else { + /* Unfortunately there's no place for this pollfd, so request a rebuild of the array */ + w->idx = -1; + s->rebuild_pollfds = 1; + } + + AVAHI_LLIST_PREPEND(AvahiWatch, watches, s->watches, w); + s->n_watches++; + + return w; +} + +static void watch_update(AvahiWatch *w, AvahiWatchEvent events) { + assert(w); + assert(!w->dead); + + w->pollfd.events = events; + + if (w->idx != -1) { + assert(w->simple_poll); + w->simple_poll->pollfds[w->idx] = w->pollfd; + } else + w->simple_poll->rebuild_pollfds = 1; +} + +static void remove_pollfd(AvahiWatch *w) { + assert(w); + + if (w->idx == -1) + return; + + if (w->idx == w->simple_poll->n_pollfds-1) { + + /* This pollfd is at the end of the array, so we can easily cut it */ + + assert(w->simple_poll->n_pollfds > 0); + w->simple_poll->n_pollfds -= 1; + } else + + /* Unfortunately this pollfd is in the middle of the array, so request a rebuild of it */ + w->simple_poll->rebuild_pollfds = 1; +} + +static void watch_free(AvahiWatch *w) { + assert(w); + assert(!w->dead); + + remove_pollfd(w); + + w->dead = 1; + w->simple_poll->n_watches --; + w->simple_poll->req_cleanup = 1; +} + +static void set_wakeup_time(AvahiPoll *api, const struct timeval *tv) { + AvahiSimplePoll *s; + + assert(api); + s = api->userdata; + + if (tv) { + s->wakeup = *tv; + s->use_wakeup = 1; + } else + s->use_wakeup = 0; +} + +static void destroy_watch(AvahiWatch *w) { + assert(w); + + remove_pollfd(w); + AVAHI_LLIST_REMOVE(AvahiWatch, watches, w->simple_poll->watches, w); + + if (!w->dead) + w->simple_poll->n_watches --; + + avahi_free(w); +} + +static void cleanup(AvahiSimplePoll *s, int all) { + AvahiWatch *w, *next; + assert(s); + + for (w = s->watches; w; w = next) { + next = w->watches_next; + + if (all || w->dead) + destroy_watch(w); + } + + s->req_cleanup = 0; +} + +AvahiSimplePoll *avahi_simple_poll_new(void) { + AvahiSimplePoll *s; + + if (!(s = avahi_new(AvahiSimplePoll, 1))) + return NULL; + + s->api.userdata = s; + s->api.watch_new = watch_new; + s->api.watch_free = watch_free; + s->api.watch_update = watch_update; + s->api.set_wakeup_time = set_wakeup_time; + s->pollfds = NULL; + s->max_pollfds = s->n_pollfds = 0; + s->use_wakeup = 0; + s->rebuild_pollfds = 0; + s->quit = 0; + s->n_watches = 0; + s->req_cleanup = 0; + + AVAHI_LLIST_HEAD_INIT(AvahiWatch, s->watches); + + return s; +} + +void avahi_simple_poll_free(AvahiSimplePoll *s) { + assert(s); + + cleanup(s, 1); + + assert(s->n_watches == 0); + + avahi_free(s->pollfds); + avahi_free(s); +} + +static int rebuild(AvahiSimplePoll *s) { + AvahiWatch *w; + int idx; + + assert(s); + + if (s->n_watches > s->max_pollfds) { + struct pollfd *n; + + s->max_pollfds = s->n_watches + 10; + + if (!(n = avahi_realloc(s->pollfds, sizeof(struct pollfd) * s->max_pollfds))) + return -1; + + s->pollfds = n; + } + + for (idx = 0, w = s->watches; w; w = w->watches_next) { + + if(w->dead) + continue; + + assert(w->idx < s->max_pollfds); + s->pollfds[w->idx = idx++] = w->pollfd; + } + + s->n_pollfds = idx; + + s->rebuild_pollfds = 0; + + return 0; +} + +int avahi_simple_poll_iterate(AvahiSimplePoll *s, int block) { + int timeout, r, ret = 0; + assert(s); + + if (s->quit) + return 1; + + if (s->req_cleanup) + cleanup(s, 0); + + if (s->rebuild_pollfds) + if (rebuild(s) < 0) + return -1; + + if (block) { + if (s->use_wakeup) { + struct timeval now; + AvahiUsec usec; + + gettimeofday(&now, NULL); + + usec = avahi_timeval_diff(&s->wakeup, &now); + + timeout = usec <= 0 ? 0 : (int) (usec / 1000); + } else + timeout = -1; + } else + timeout = 0; + + if ((r = poll(s->pollfds, s->n_pollfds, timeout)) < 0) + return -1; + + else if (r > 0) { + AvahiWatch *w; + + for (w = s->watches; w; w = w->watches_next) { + + if (w->dead) + continue; + + assert(w->idx >= 0); + assert(w->idx < s->n_pollfds); + + if (s->pollfds[w->idx].revents > 0) + w->callback(w, w->pollfd.fd, s->pollfds[w->idx].revents, w->userdata); + + if (s->quit) { + ret = 1; + goto finish; + } + } + } + + ret = 0; + +finish: + + if (s->req_cleanup) + cleanup(s, 0); + + return ret; +} + +void avahi_simple_poll_quit(AvahiSimplePoll *w) { + assert(w); + + w->quit = 1; +} + +AvahiPoll* avahi_simple_poll_get(AvahiSimplePoll *s) { + assert(s); + + return &s->api; +} diff --git a/avahi-common/simple-watch.h b/avahi-common/simple-watch.h new file mode 100644 index 0000000..600e5ce --- /dev/null +++ b/avahi-common/simple-watch.h @@ -0,0 +1,44 @@ +#ifndef foosimplewatchhfoo +#define foosimplewatchhfoo + +/* $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. +***/ + +#include + +#include "watch.h" + +AVAHI_C_DECL_BEGIN + +typedef struct AvahiSimplePoll AvahiSimplePoll; + +AvahiSimplePoll *avahi_simple_poll_new(void); +void avahi_simple_poll_free(AvahiSimplePoll *s); + +AvahiPoll* avahi_simple_poll_get(AvahiSimplePoll *s); + +int avahi_simple_poll_iterate(AvahiSimplePoll *s, int block); + +void avahi_simple_poll_quit(AvahiSimplePoll *s); + +AVAHI_C_DECL_END + +#endif diff --git a/avahi-common/timeval-test.c b/avahi-common/timeval-test.c new file mode 100644 index 0000000..7dedf41 --- /dev/null +++ b/avahi-common/timeval-test.c @@ -0,0 +1,41 @@ +/* $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 +#endif + +#include +#include "timeval.h" + +int main(int argc, char *argv[]) { + + struct timeval a = { 5, 5 }, b; + + b = a; + + printf("%li.%li\n", a.tv_sec, a.tv_usec); + avahi_timeval_add(&a, -50); + + printf("%li.%li\n", a.tv_sec, a.tv_usec); + + printf("%lli\n", avahi_timeval_diff(&a, &b)); +} diff --git a/avahi-common/timeval.c b/avahi-common/timeval.c new file mode 100644 index 0000000..e5732cd --- /dev/null +++ b/avahi-common/timeval.c @@ -0,0 +1,101 @@ +/* $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 +#endif + +#include +#include + +#include "timeval.h" + +int avahi_timeval_compare(const struct timeval *a, const struct timeval *b) { + assert(a); + assert(b); + + if (a->tv_sec < b->tv_sec) + return -1; + + if (a->tv_sec > b->tv_sec) + return 1; + + if (a->tv_usec < b->tv_usec) + return -1; + + if (a->tv_usec > b->tv_usec) + return 1; + + return 0; +} + +AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b) { + assert(a); + assert(b); + + if (avahi_timeval_compare(a, b) < 0) + return - avahi_timeval_diff(b, a); + + return ((AvahiUsec) a->tv_sec - b->tv_sec)*1000000 + a->tv_usec - b->tv_usec; +} + +struct timeval* avahi_timeval_add(struct timeval *a, AvahiUsec usec) { + AvahiUsec u; + assert(a); + + u = usec + a->tv_usec; + + if (u < 0) { + a->tv_usec = (long) (1000000 + (u % 1000000)); + a->tv_sec += (long) (-1 + (u / 1000000)); + } else { + a->tv_usec = (long) (u % 1000000); + a->tv_sec += (long) (u / 1000000); + } + + return a; +} + +AvahiUsec avahi_age(const struct timeval *a) { + struct timeval now; + + assert(a); + + gettimeofday(&now, NULL); + + return avahi_timeval_diff(&now, a); +} + + +struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { + assert(tv); + + gettimeofday(tv, NULL); + + if (msec) + avahi_timeval_add(tv, (AvahiUsec) msec*1000); + + if (jitter) + avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); + + return tv; +} + diff --git a/avahi-common/timeval.h b/avahi-common/timeval.h new file mode 100644 index 0000000..c046a19 --- /dev/null +++ b/avahi-common/timeval.h @@ -0,0 +1,43 @@ +#ifndef footimevalhfoo +#define footimevalhfoo + +/* $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. +***/ + +#include +#include + +#include + +AVAHI_C_DECL_BEGIN + +typedef int64_t AvahiUsec; + +int avahi_timeval_compare(const struct timeval *a, const struct timeval *b); +AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b); +struct timeval* avahi_timeval_add(struct timeval *a, AvahiUsec usec); + +AvahiUsec avahi_age(const struct timeval *a); +struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter); + +AVAHI_C_DECL_END + +#endif diff --git a/avahi-common/watch-test.c b/avahi-common/watch-test.c new file mode 100644 index 0000000..f87a303 --- /dev/null +++ b/avahi-common/watch-test.c @@ -0,0 +1,81 @@ +/* $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 +#endif + +#include +#include +#include +#include +#include + +#include "watch.h" +#include "simple-watch.h" +#include "timeval.h" + +static AvahiPoll *api = NULL; + +static void callback(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdata) { + + if (event & AVAHI_WATCH_IN) { + ssize_t r; + char c; + + if ((r = read(fd, &c, 1)) <= 0) { + fprintf(stderr, "read() failed: %s\n", r < 0 ? strerror(errno) : "EOF"); + api->watch_free(w); + return; + } + + printf("Read: %c\n", c >= 32 && c < 127 ? c : '.'); + } +} + +int main(int argc, char *argv[]) { + int i = 0; + AvahiSimplePoll *s; + + s = avahi_simple_poll_new(); + assert(s); + + api = avahi_simple_poll_get(s); + + api->watch_new(api, 0, AVAHI_WATCH_IN, callback, NULL); + + for (;;) { + struct timeval tv; + printf("Iteration %i\n", i++); + + if (i > 100) + avahi_simple_poll_quit(s); + + avahi_elapse_time(&tv, 1000, 0); + + api->set_wakeup_time(api, &tv); + + if (avahi_simple_poll_iterate(s, 1) != 0) + break; + } + + return 0; +} diff --git a/avahi-common/watch.h b/avahi-common/watch.h new file mode 100644 index 0000000..b26c2ba --- /dev/null +++ b/avahi-common/watch.h @@ -0,0 +1,57 @@ +#ifndef foowatchhfoo +#define foowatchhfoo + +/* $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. +***/ + +#include +#include + +#include "timeval.h" + +AVAHI_C_DECL_BEGIN + +typedef struct AvahiWatch AvahiWatch; +typedef struct AvahiPoll AvahiPoll; + +typedef enum { + AVAHI_WATCH_IN = POLLIN, + AVAHI_WATCH_OUT = POLLOUT, + AVAHI_WATCH_ERR = POLLERR, + AVAHI_WATCH_HUP = POLLHUP +} AvahiWatchEvent; + +typedef void (*AvahiWatchCallback)(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdata); + +struct AvahiPoll { + void* userdata; + + AvahiWatch* (*watch_new)(AvahiPoll *api, int fd, AvahiWatchEvent event, AvahiWatchCallback callback, void *userdata); + void (*watch_update)(AvahiWatch *w, AvahiWatchEvent event); + void (*watch_free)(AvahiWatch *w); + + void (*set_wakeup_time)(AvahiPoll *api, const struct timeval *tv); +}; + +AVAHI_C_DECL_END + +#endif + diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index e15f295..c71d6ed 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -24,7 +24,6 @@ AM_CFLAGS+=$(GLIB20_CFLAGS) AM_LDADD=$(GLIB20_LIBS) # Import stuff from avahi-common -AM_CFLAGS+=-I$(top_srcdir)/avahi-common COMMON_LDADD=../avahi-common/libavahi-common.la # This cool debug trap works on i386/gcc only @@ -46,8 +45,7 @@ noinst_PROGRAMS = \ conformance-test \ avahi-reflector \ dns-test \ - timeeventq-test \ - timeval-test + timeeventq-test libavahi_core_la_SOURCES = \ timeeventq.c timeeventq.h\ @@ -75,8 +73,8 @@ libavahi_core_la_SOURCES = \ log.c log.h \ browse-dns-server.c \ fdutil.h fdutil.c \ - timeval.h timeval.c \ util.c util.h + libavahi_core_la_CFLAGS = $(AM_CFLAGS) libavahi_core_la_LIBADD = $(AM_LDADD) $(COMMON_LDADD) @@ -113,17 +111,10 @@ dns_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) timeeventq_test_SOURCES = \ timeeventq-test.c \ timeeventq.h timeeventq.c \ - timeval.c timeval.h \ prioq.h prioq.c timeeventq_test_CFLAGS = $(AM_CFLAGS) timeeventq_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) -timeval_test_SOURCES = \ - timeval.c timeval.h \ - timeval-test.c -timeval_test_CFLAGS = $(AM_CFLAGS) -timeval_test_LDADD = $(AM_LDADD) - valgrind: avahi-test libtool --mode=execute valgrind ./avahi-test diff --git a/avahi-core/announce.c b/avahi-core/announce.c index 3787f8f..9a6d505 100644 --- a/avahi-core/announce.c +++ b/avahi-core/announce.c @@ -23,8 +23,8 @@ #include #endif +#include #include "announce.h" -#include "timeval.h" #define AVAHI_ANNOUNCEMENT_JITTER_MSEC 250 #define AVAHI_PROBE_JITTER_MSEC 250 diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index 5db2473..7156d06 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -152,7 +152,7 @@ fail: group = NULL; } -static void hnr_callback(AvahiHostNameResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) { +static void hnr_callback(AvahiHostNameResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) { gchar t[64]; if (a) @@ -161,7 +161,7 @@ static void hnr_callback(AvahiHostNameResolver *r, AvahiIfIndex iface, AvahiProt avahi_log_debug("HNR: (%i.%i) <%s> -> %s [%s]", iface, protocol, hostname, a ? t : "n/a", event == AVAHI_RESOLVER_FOUND ? "found" : "timeout"); } -static void ar_callback(AvahiAddressResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) { +static void ar_callback(AvahiAddressResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) { gchar t[64]; avahi_address_snprint(t, sizeof(t), a); @@ -183,7 +183,7 @@ static void sb_callback(AvahiServiceBrowser *b, AvahiIfIndex iface, AvahiProtoco avahi_log_debug("SB: (%i.%i) <%s> as %s in <%s> [%s]", iface, protocol, name, service_type, domain, event == AVAHI_BROWSER_NEW ? "new" : "remove"); } -static void sr_callback(AvahiServiceResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiBrowserEvent event, const gchar *name, const gchar*service_type, const gchar*domain_name, const gchar*hostname, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) { +static void sr_callback(AvahiServiceResolver *r, AvahiIfIndex iface, AvahiProtocol protocol, AvahiResolverEvent event, const gchar *name, const gchar*service_type, const gchar*domain_name, const gchar*hostname, const AvahiAddress *a, guint16 port, AvahiStringList *txt, gpointer userdata) { if (event == AVAHI_RESOLVER_TIMEOUT) avahi_log_debug("SR: (%i.%i) <%s> as %s in <%s> [timeout]", iface, protocol, name, service_type, domain_name); diff --git a/avahi-core/browse.c b/avahi-core/browse.c index e2d996e..6357095 100644 --- a/avahi-core/browse.c +++ b/avahi-core/browse.c @@ -23,8 +23,8 @@ #include #endif +#include #include "browse.h" -#include "timeval.h" #include "log.h" struct AvahiRecordBrowser { diff --git a/avahi-core/cache.c b/avahi-core/cache.c index dddd5ee..ebe78fc 100644 --- a/avahi-core/cache.c +++ b/avahi-core/cache.c @@ -25,7 +25,7 @@ #include -#include "timeval.h" +#include #include "cache.h" #include "log.h" @@ -215,10 +215,10 @@ static void update_time_event(AvahiCache *c, AvahiCacheEntry *e) { } static void next_expiry(AvahiCache *c, AvahiCacheEntry *e, guint percent) { + AvahiUsec usec; g_assert(c); g_assert(e); g_assert(percent > 0 && percent <= 100); - AvahiUsec usec; /* gchar *txt; */ usec = ((AvahiUsec) e->record->ttl) * 10000; diff --git a/avahi-core/conformance-test.c b/avahi-core/conformance-test.c index 7a4c601..c14a761 100644 --- a/avahi-core/conformance-test.c +++ b/avahi-core/conformance-test.c @@ -30,8 +30,8 @@ #include #include +#include #include "core.h" -#include "alternative.h" #include "log.h" static gchar *name = NULL; diff --git a/avahi-core/iface.h b/avahi-core/iface.h index cb76359..47c54ba 100644 --- a/avahi-core/iface.h +++ b/avahi-core/iface.h @@ -30,7 +30,7 @@ typedef struct AvahiInterface AvahiInterface; typedef struct AvahiHwInterface AvahiHwInterface; #include -#include "address.h" +#include #include "server.h" #include "netlink.h" #include "cache.h" diff --git a/avahi-core/probe-sched.c b/avahi-core/probe-sched.c index d7f9ca0..a375c7b 100644 --- a/avahi-core/probe-sched.c +++ b/avahi-core/probe-sched.c @@ -24,9 +24,9 @@ #endif #include +#include #include "probe-sched.h" -#include "timeval.h" #include "log.h" #define AVAHI_PROBE_HISTORY_MSEC 150 diff --git a/avahi-core/probe-sched.h b/avahi-core/probe-sched.h index 07933a7..aae0f3a 100644 --- a/avahi-core/probe-sched.h +++ b/avahi-core/probe-sched.h @@ -24,8 +24,8 @@ typedef struct AvahiProbeScheduler AvahiProbeScheduler; +#include #include "iface.h" -#include "address.h" AvahiProbeScheduler *avahi_probe_scheduler_new(AvahiInterface *i); void avahi_probe_scheduler_free(AvahiProbeScheduler *s); diff --git a/avahi-core/query-sched.c b/avahi-core/query-sched.c index 6e9234f..9a26dba 100644 --- a/avahi-core/query-sched.c +++ b/avahi-core/query-sched.c @@ -23,8 +23,8 @@ #include #endif +#include #include "query-sched.h" -#include "timeval.h" #define AVAHI_QUERY_HISTORY_MSEC 100 #define AVAHI_QUERY_DEFER_MSEC 100 diff --git a/avahi-core/query-sched.h b/avahi-core/query-sched.h index b77363c..2c373b1 100644 --- a/avahi-core/query-sched.h +++ b/avahi-core/query-sched.h @@ -24,8 +24,8 @@ typedef struct AvahiQueryScheduler AvahiQueryScheduler; +#include #include "iface.h" -#include "address.h" AvahiQueryScheduler *avahi_query_scheduler_new(AvahiInterface *i); void avahi_query_scheduler_free(AvahiQueryScheduler *s); diff --git a/avahi-core/resolve-address.c b/avahi-core/resolve-address.c index fa50c39..6bd7cf2 100644 --- a/avahi-core/resolve-address.c +++ b/avahi-core/resolve-address.c @@ -23,8 +23,8 @@ #include #endif +#include #include "browse.h" -#include "timeval.h" struct AvahiAddressResolver { AvahiServer *server; diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c index f50ddb4..50fbcf8 100644 --- a/avahi-core/resolve-host-name.c +++ b/avahi-core/resolve-host-name.c @@ -24,7 +24,7 @@ #endif #include -#include "timeval.h" +#include #include "browse.h" struct AvahiHostNameResolver { diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c index bf4f7b9..0e4e119 100644 --- a/avahi-core/resolve-service.c +++ b/avahi-core/resolve-service.c @@ -26,8 +26,8 @@ #include #include +#include #include "browse.h" -#include "timeval.h" struct AvahiServiceResolver { AvahiServer *server; diff --git a/avahi-core/response-sched.c b/avahi-core/response-sched.c index 6027287..efb6677 100644 --- a/avahi-core/response-sched.c +++ b/avahi-core/response-sched.c @@ -23,8 +23,8 @@ #include #endif +#include #include "response-sched.h" -#include "timeval.h" #include "log.h" #define AVAHI_RESPONSE_HISTORY_MSEC 500 diff --git a/avahi-core/response-sched.h b/avahi-core/response-sched.h index 10fd821..3760a44 100644 --- a/avahi-core/response-sched.h +++ b/avahi-core/response-sched.h @@ -24,8 +24,8 @@ typedef struct AvahiResponseScheduler AvahiResponseScheduler; +#include #include "iface.h" -#include "address.h" AvahiResponseScheduler *avahi_response_scheduler_new(AvahiInterface *i); void avahi_response_scheduler_free(AvahiResponseScheduler *s); diff --git a/avahi-core/server.c b/avahi-core/server.c index d913738..241932f 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -32,9 +32,9 @@ #include #include +#include #include "server.h" -#include "timeval.h" #include "iface.h" #include "socket.h" #include "browse.h" @@ -459,9 +459,9 @@ void avahi_server_generate_response(AvahiServer *s, AvahiInterface *i, AvahiDnsP reply = avahi_dns_packet_new_reply(p, size, FALSE, TRUE); if (!avahi_dns_packet_append_record(reply, r, flush_cache, 0)) { + gchar *t; avahi_dns_packet_free(reply); - - gchar *t = avahi_record_to_string(r); + t = avahi_record_to_string(r); avahi_log_warn("Record [%s] too large, doesn't fit in any packet!", t); g_free(t); break; diff --git a/avahi-core/timeeventq-test.c b/avahi-core/timeeventq-test.c index 6ac55b8..613d438 100644 --- a/avahi-core/timeeventq-test.c +++ b/avahi-core/timeeventq-test.c @@ -25,8 +25,8 @@ #include +#include #include "timeeventq.h" -#include "timeval.h" static AvahiTimeEventQueue *q = NULL; diff --git a/avahi-core/timeeventq.c b/avahi-core/timeeventq.c index d466cd4..88e1779 100644 --- a/avahi-core/timeeventq.c +++ b/avahi-core/timeeventq.c @@ -23,8 +23,8 @@ #include #endif +#include #include "timeeventq.h" -#include "timeval.h" static gint compare(gconstpointer _a, gconstpointer _b) { const AvahiTimeEvent *a = _a, *b = _b; diff --git a/avahi-core/timeval-test.c b/avahi-core/timeval-test.c deleted file mode 100644 index 7dedf41..0000000 --- a/avahi-core/timeval-test.c +++ /dev/null @@ -1,41 +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 -#endif - -#include -#include "timeval.h" - -int main(int argc, char *argv[]) { - - struct timeval a = { 5, 5 }, b; - - b = a; - - printf("%li.%li\n", a.tv_sec, a.tv_usec); - avahi_timeval_add(&a, -50); - - printf("%li.%li\n", a.tv_sec, a.tv_usec); - - printf("%lli\n", avahi_timeval_diff(&a, &b)); -} diff --git a/avahi-core/timeval.c b/avahi-core/timeval.c deleted file mode 100644 index e5732cd..0000000 --- a/avahi-core/timeval.c +++ /dev/null @@ -1,101 +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 -#endif - -#include -#include - -#include "timeval.h" - -int avahi_timeval_compare(const struct timeval *a, const struct timeval *b) { - assert(a); - assert(b); - - if (a->tv_sec < b->tv_sec) - return -1; - - if (a->tv_sec > b->tv_sec) - return 1; - - if (a->tv_usec < b->tv_usec) - return -1; - - if (a->tv_usec > b->tv_usec) - return 1; - - return 0; -} - -AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b) { - assert(a); - assert(b); - - if (avahi_timeval_compare(a, b) < 0) - return - avahi_timeval_diff(b, a); - - return ((AvahiUsec) a->tv_sec - b->tv_sec)*1000000 + a->tv_usec - b->tv_usec; -} - -struct timeval* avahi_timeval_add(struct timeval *a, AvahiUsec usec) { - AvahiUsec u; - assert(a); - - u = usec + a->tv_usec; - - if (u < 0) { - a->tv_usec = (long) (1000000 + (u % 1000000)); - a->tv_sec += (long) (-1 + (u / 1000000)); - } else { - a->tv_usec = (long) (u % 1000000); - a->tv_sec += (long) (u / 1000000); - } - - return a; -} - -AvahiUsec avahi_age(const struct timeval *a) { - struct timeval now; - - assert(a); - - gettimeofday(&now, NULL); - - return avahi_timeval_diff(&now, a); -} - - -struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { - assert(tv); - - gettimeofday(tv, NULL); - - if (msec) - avahi_timeval_add(tv, (AvahiUsec) msec*1000); - - if (jitter) - avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); - - return tv; -} - diff --git a/avahi-core/timeval.h b/avahi-core/timeval.h deleted file mode 100644 index c046a19..0000000 --- a/avahi-core/timeval.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef footimevalhfoo -#define footimevalhfoo - -/* $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. -***/ - -#include -#include - -#include - -AVAHI_C_DECL_BEGIN - -typedef int64_t AvahiUsec; - -int avahi_timeval_compare(const struct timeval *a, const struct timeval *b); -AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b); -struct timeval* avahi_timeval_add(struct timeval *a, AvahiUsec usec); - -AvahiUsec avahi_age(const struct timeval *a); -struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter); - -AVAHI_C_DECL_END - -#endif diff --git a/avahi-glib/Makefile.am b/avahi-glib/Makefile.am new file mode 100644 index 0000000..6cfc46e --- /dev/null +++ b/avahi-glib/Makefile.am @@ -0,0 +1,57 @@ +# $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 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 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. + +AM_CFLAGS=-I$(top_srcdir) + +# GLIB 2.0 +AM_CFLAGS+=$(GLIB20_CFLAGS) +AM_LDADD=$(GLIB20_LIBS) + +# Import stuff from avahi-common +COMMON_LDADD=../avahi-common/libavahi-common.la + +# This cool debug trap works on i386/gcc only +AM_CFLAGS+='-DDEBUG_TRAP=__asm__("int $$3")' + +avahiincludedir=$(includedir)/avahi-glib + +avahiinclude_HEADERS = \ + glib-watch.h + +lib_LTLIBRARIES = \ + libavahi-glib.la + +noinst_PROGRAMS = \ + glib-watch-test + +libavahi_glib_la_SOURCES = \ + glib-watch.c glib-watch.h +libavahi_glib_la_CFLAGS = $(AM_CFLAGS) +libavahi_glib_la_LIBADD = $(AM_LDADD) $(COMMON_LDADD) + +glib_watch_test_SOURCES = \ + glib-watch.c glib-watch.h \ + glib-watch-test.c +glib_watch_test_CFLAGS = $(AM_CFLAGS) +glib_watch_test_LDADD = $(AM_LDADD) $(COMMON_LDADD) + + + + + diff --git a/avahi-glib/glib-watch-test.c b/avahi-glib/glib-watch-test.c new file mode 100644 index 0000000..5072321 --- /dev/null +++ b/avahi-glib/glib-watch-test.c @@ -0,0 +1,87 @@ +/* $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 +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include "glib-watch.h" + +static AvahiPoll *api = NULL; +static GMainLoop *loop = NULL; + +static void callback(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdata) { + + if (event & AVAHI_WATCH_IN) { + ssize_t r; + char c; + + if ((r = read(fd, &c, 1)) <= 0) { + fprintf(stderr, "read() failed: %s\n", r < 0 ? strerror(errno) : "EOF"); + api->watch_free(w); + return; + } + + printf("Read: %c\n", c >= 32 && c < 127 ? c : '.'); + } +} + +static void iteration(AvahiGLibPoll *p, void *userdata) { + struct timeval tv; + static int i = 0; + + printf("Iteration %i\n", i++); + + if (i > 100) + g_main_loop_quit(loop); + + avahi_elapse_time(&tv, 1000, 0); + api->set_wakeup_time(api, &tv); +} + +int main(int argc, char *argv[]) { + AvahiGLibPoll *s; + struct timeval tv; + + s = avahi_glib_poll_new(NULL, iteration, NULL); + assert(s); + + api = avahi_glib_poll_get(s); + + api->watch_new(api, 0, AVAHI_WATCH_IN, callback, NULL); + + avahi_elapse_time(&tv, 1000, 0); + api->set_wakeup_time(api, &tv); + + loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(loop); + g_main_loop_unref(loop); + + return 0; +} diff --git a/avahi-glib/glib-watch.c b/avahi-glib/glib-watch.c new file mode 100644 index 0000000..7eab84b --- /dev/null +++ b/avahi-glib/glib-watch.c @@ -0,0 +1,261 @@ +/* $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 +#endif + +#include +#include + +#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 AvahiGLibPoll { + GSource source; + AvahiPoll api; + GMainContext *context; + + struct timeval wakeup; + gboolean use_wakeup; + int req_cleanup; + + AvahiGLibProcessCallback process_callback; + void *userdata; + + AVAHI_LLIST_HEAD(AvahiWatch, watches); +}; + +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(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->req_cleanup = 0; +} + +static AvahiWatch* watch_new(AvahiPoll *api, int fd, AvahiWatchEvent event, 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 = + (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->callback = callback; + w->userdata = userdata; + w->dead = 0; + + g_source_add_poll(&g->source, &w->pollfd); + w->pollfd_added = 1; + + 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 = events; +} + +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->dead = 1; + w->glib_poll->req_cleanup = 1; +} + +static void set_wakeup_time(AvahiPoll *api, const struct timeval *tv) { + AvahiGLibPoll *g; + + assert(api); + g = api->userdata; + + if (tv) { + g->wakeup = *tv; + g->use_wakeup = 1; + } else + g->use_wakeup = 0; +} + +static gboolean prepare_func(GSource *source, gint *timeout) { + AvahiGLibPoll *g = (AvahiGLibPoll*) source; + + g_assert(g); + g_assert(timeout); + + if (g->use_wakeup) { + 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(&g->wakeup, &tvnow); + + if (usec <= 0) + return TRUE; + + *timeout = (gint) (usec / 1000); + } + + return FALSE; +} + +static gboolean check_func(GSource *source) { + AvahiGLibPoll *g = (AvahiGLibPoll*) source; + AvahiWatch *w; + + g_assert(g); + + for (w = g->watches; w; w = w->watches_next) + if (w->pollfd.revents > 0) + return TRUE; + + return FALSE; +} + +static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) { + AvahiGLibPoll* g = (AvahiGLibPoll*) source; + AvahiWatch *w; + + g_assert(g); + + if (g->req_cleanup) + cleanup(g, 0); + + if (g->process_callback) + g->process_callback(g, g->userdata); + + 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->pollfd.revents = 0; + } + + if (g->req_cleanup) + cleanup(g, 0); + + return TRUE; +} + +AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, AvahiGLibProcessCallback callback, void *userdata) { + 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.set_wakeup_time = set_wakeup_time; + + g->use_wakeup = 0; + g->process_callback = callback; + g->userdata = userdata; + g->req_cleanup = 0; + + AVAHI_LLIST_HEAD_INIT(AvahiWatch, g->watches); + + g_source_attach(&g->source, g->context); + + return g; +} + +void avahi_glib_poll_free(AvahiGLibPoll *g) { + GSource *s = &g->source; + assert(g); + + cleanup(g, 1); + + g_main_context_unref(g->context); + g_source_destroy(s); + g_source_unref(s); +} + +AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g) { + assert(g); + + return &g->api; +} diff --git a/avahi-glib/glib-watch.h b/avahi-glib/glib-watch.h new file mode 100644 index 0000000..9df58b5 --- /dev/null +++ b/avahi-glib/glib-watch.h @@ -0,0 +1,43 @@ +#ifndef fooglibwatchhfoo +#define fooglibwatchhfoo + +/* $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. +***/ + +#include + +#include +#include + +AVAHI_C_DECL_BEGIN + +typedef struct AvahiGLibPoll AvahiGLibPoll; + +typedef void (*AvahiGLibProcessCallback)(AvahiGLibPoll *g, void *userdata); + +AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, AvahiGLibProcessCallback callback, void *userdata); +void avahi_glib_poll_free(AvahiGLibPoll *g); + +AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g); + +AVAHI_C_DECL_END + +#endif diff --git a/configure.ac b/configure.ac index f27a959..6278af6 100644 --- a/configure.ac +++ b/configure.ac @@ -279,6 +279,7 @@ Makefile avahi-core.pc avahi-common/Makefile avahi-core/Makefile +avahi-glib/Makefile avahi-daemon/Makefile avahi-daemon/avahi-dbus.conf avahi-discover-standalone/Makefile diff --git a/docs/TODO b/docs/TODO index 5ce60ce..6f7446a 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,4 +1,7 @@ todo: +* drop glib +* allow srv port == 0 +* deal with no local interface * release! later: