From 4f0a5e7572a4257894b4bfede42c26d65152609e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 13 Aug 2005 21:25:09 +0000 Subject: * strip glib from avahi-core * implement glib memory allocator * add new documentation file MALLOC * initialize pseudo-RNG from /dev/urandom in avahi-daemon * remove some gcc 4.0 warnings * beef up watch system with real timeouts * move GCC __attribute__ macros into its own header avahi-common/gccmacro.h * make use of GCC's sentinel attribute where it make sense * add malloc() implementations that abort on OOM and enable them by default git-svn-id: file:///home/lennart/svn/public/avahi/trunk@308 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-glib/Makefile.am | 4 +- avahi-glib/glib-malloc.c | 57 ++++++++++++++++++++++++++ avahi-glib/glib-malloc.h | 45 +++++++++++++++++++++ avahi-glib/glib-watch-test.c | 12 +++--- avahi-glib/glib-watch.c | 95 ++++++++++++++++++++++++++++++++------------ avahi-glib/glib-watch.h | 9 ++--- 6 files changed, 184 insertions(+), 38 deletions(-) create mode 100644 avahi-glib/glib-malloc.c create mode 100644 avahi-glib/glib-malloc.h (limited to 'avahi-glib') diff --git a/avahi-glib/Makefile.am b/avahi-glib/Makefile.am index 6cfc46e..dd5a14f 100644 --- a/avahi-glib/Makefile.am +++ b/avahi-glib/Makefile.am @@ -33,6 +33,7 @@ avahiincludedir=$(includedir)/avahi-glib avahiinclude_HEADERS = \ glib-watch.h + glib-malloc.h lib_LTLIBRARIES = \ libavahi-glib.la @@ -41,7 +42,8 @@ noinst_PROGRAMS = \ glib-watch-test libavahi_glib_la_SOURCES = \ - glib-watch.c glib-watch.h + glib-watch.c glib-watch.h \ + glib-malloc.h glib-malloc.c libavahi_glib_la_CFLAGS = $(AM_CFLAGS) libavahi_glib_la_LIBADD = $(AM_LDADD) $(COMMON_LDADD) diff --git a/avahi-glib/glib-malloc.c b/avahi-glib/glib-malloc.c new file mode 100644 index 0000000..2968abc --- /dev/null +++ b/avahi-glib/glib-malloc.c @@ -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.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-malloc.h" + +static void* malloc_glue(size_t l) { + return g_malloc(l); +} + +static void* realloc_glue(void *p, size_t l) { + return g_realloc(p, l); +} + +static void* calloc_glue(size_t nmemb, size_t size) { + return g_malloc0(nmemb * size); +} + +const AvahiAllocator *avahi_glib_allocator(void) { + + static AvahiAllocator allocator; + static int allocator_initialized = 0; + + if (!allocator_initialized) { + allocator.malloc = malloc_glue; + allocator.free = g_free; + allocator.realloc = realloc_glue; + allocator.calloc = calloc_glue; + allocator_initialized = 1; + } + + return &allocator; +} diff --git a/avahi-glib/glib-malloc.h b/avahi-glib/glib-malloc.h new file mode 100644 index 0000000..7ce8269 --- /dev/null +++ b/avahi-glib/glib-malloc.h @@ -0,0 +1,45 @@ +#ifndef fooglibmallochfoo +#define fooglibmallochfoo + +/* $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. +***/ + +/** \file glib-malloc.h GLib's memory allocator for Avahi */ + +#include + +#include +#include + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +AVAHI_C_DECL_BEGIN +#endif + +/** Return a pointer to a memory allocator that uses GLib's g_malloc() + and frinds. Th returned structure is statically allocated, and needs + not to be copied or freed. Pass this directly to avahi_set_allocator(). */ +const AvahiAllocator * avahi_glib_allocator(void); + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +AVAHI_C_DECL_END +#endif + +#endif diff --git a/avahi-glib/glib-watch-test.c b/avahi-glib/glib-watch-test.c index 5072321..bd111dd 100644 --- a/avahi-glib/glib-watch-test.c +++ b/avahi-glib/glib-watch-test.c @@ -52,24 +52,24 @@ static void callback(AvahiWatch *w, int fd, AvahiWatchEvent event, void *userdat } } -static void iteration(AvahiGLibPoll *p, void *userdata) { +static void wakeup(AvahiPoll *_api, void *userdata) { struct timeval tv; static int i = 0; - printf("Iteration %i\n", i++); + printf("Wakeup #%i\n", i++); - if (i > 100) + if (i > 10) g_main_loop_quit(loop); avahi_elapse_time(&tv, 1000, 0); - api->set_wakeup_time(api, &tv); + api->set_wakeup(api, &tv, wakeup, NULL); } int main(int argc, char *argv[]) { AvahiGLibPoll *s; struct timeval tv; - s = avahi_glib_poll_new(NULL, iteration, NULL); + s = avahi_glib_poll_new(NULL); assert(s); api = avahi_glib_poll_get(s); @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) { api->watch_new(api, 0, AVAHI_WATCH_IN, callback, NULL); avahi_elapse_time(&tv, 1000, 0); - api->set_wakeup_time(api, &tv); + api->set_wakeup(api, &tv, wakeup, NULL); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); diff --git a/avahi-glib/glib-watch.c b/avahi-glib/glib-watch.c index 7eab84b..4af2390 100644 --- a/avahi-glib/glib-watch.c +++ b/avahi-glib/glib-watch.c @@ -45,13 +45,12 @@ struct AvahiGLibPoll { GMainContext *context; struct timeval wakeup; - gboolean use_wakeup; - int req_cleanup; + AvahiWakeupCallback wakeup_callback; + void *wakeup_userdata; - AvahiGLibProcessCallback process_callback; - void *userdata; + int req_cleanup; - AVAHI_LLIST_HEAD(AvahiWatch, watches); + AVAHI_LLIST_HEAD(AvahiWatch, watches); }; static void destroy_watch(AvahiWatch *w) { @@ -133,17 +132,43 @@ static void watch_free(AvahiWatch *w) { w->glib_poll->req_cleanup = 1; } -static void set_wakeup_time(AvahiPoll *api, const struct timeval *tv) { +static void set_wakeup(AvahiPoll *api, const struct timeval *tv, AvahiWakeupCallback callback, void *userdata) { AvahiGLibPoll *g; assert(api); g = api->userdata; - if (tv) { - g->wakeup = *tv; - g->use_wakeup = 1; + 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->use_wakeup = 0; + g->wakeup_callback = NULL; +} + +static void start_wakeup_callback(AvahiGLibPoll *g) { + AvahiWakeupCallback callback; + void *userdata; + + assert(g); + + /* Reset the wakeup functions, but allow changing of the two + values from the callback function */ + + callback = g->wakeup_callback; + userdata = g->wakeup_userdata; + g->wakeup_callback = NULL; + g->wakeup_userdata = NULL; + + assert(callback); + + callback(&g->api, userdata); } static gboolean prepare_func(GSource *source, gint *timeout) { @@ -152,7 +177,10 @@ static gboolean prepare_func(GSource *source, gint *timeout) { g_assert(g); g_assert(timeout); - if (g->use_wakeup) { + if (g->req_cleanup) + cleanup(g, 0); + + if (g->wakeup_callback) { GTimeVal now; struct timeval tvnow; AvahiUsec usec; @@ -178,6 +206,17 @@ static gboolean check_func(GSource *source) { g_assert(g); + if (g->wakeup_callback) { + 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) + return TRUE; + } + for (w = g->watches; w; w = w->watches_next) if (w->pollfd.revents > 0) return TRUE; @@ -191,26 +230,31 @@ static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer us g_assert(g); - if (g->req_cleanup) - cleanup(g, 0); - - if (g->process_callback) - g->process_callback(g, g->userdata); + if (g->wakeup_callback) { + 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); + 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->pollfd.revents = 0; + return TRUE; } - if (g->req_cleanup) - cleanup(g, 0); - return TRUE; } -AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, AvahiGLibProcessCallback callback, void *userdata) { +AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context) { AvahiGLibPoll *g; static GSourceFuncs source_funcs = { @@ -229,11 +273,9 @@ AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context, AvahiGLibProcessCallba 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->api.set_wakeup = set_wakeup; - g->use_wakeup = 0; - g->process_callback = callback; - g->userdata = userdata; + g->wakeup_callback = NULL; g->req_cleanup = 0; AVAHI_LLIST_HEAD_INIT(AvahiWatch, g->watches); @@ -247,11 +289,14 @@ void avahi_glib_poll_free(AvahiGLibPoll *g) { GSource *s = &g->source; assert(g); +/* g_message("BEFORE"); */ cleanup(g, 1); - + +/* g_message("MIDDLE"); */ g_main_context_unref(g->context); g_source_destroy(s); g_source_unref(s); +/* g_message("AFTER"); */ } AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g) { diff --git a/avahi-glib/glib-watch.h b/avahi-glib/glib-watch.h index 9df58b5..9e6bd68 100644 --- a/avahi-glib/glib-watch.h +++ b/avahi-glib/glib-watch.h @@ -22,20 +22,17 @@ USA. ***/ -#include - #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); +AvahiGLibPoll *avahi_glib_poll_new(GMainContext *context); void avahi_glib_poll_free(AvahiGLibPoll *g); - AvahiPoll* avahi_glib_poll_get(AvahiGLibPoll *g); AVAHI_C_DECL_END -- cgit