Ticket #149: avahi.diff

File avahi.diff, 4.6 kB (added by marcus, 2 years ago)
  • configure.ac

    old new  
    384384   AC_DEFINE([HAVE_INOTIFY], 1, [Enable Linux inotify() usage]) 
    385385fi 
    386386 
     387have_kqueue=no 
     388AC_CHECK_FUNCS([kqueue],,have_kqueue=yes) 
     389 
     390AM_CONDITIONAL(HAVE_KQUEUE, test "x$have_kqueue" = "xyes") 
     391 
     392if test "x$have_kqueue" = "xyes" ; then 
     393    AC_DEFINE([HAVE_KQUEUE], 1, [Enable BSD kqueue() usage]) 
     394fi 
     395 
    387396# Check for pkg-config manually first, as if its not installed the 
    388397# PKG_PROG_PKG_CONFIG macro won't be defined. 
    389398AC_CHECK_PROG(have_pkg_config, pkg-config, yes, no) 
  • avahi-daemon/main.c

    old new  
    5050#endif 
    5151#endif 
    5252 
     53#ifdef HAVE_KQUEUE 
     54#include <sys/types.h> 
     55#include <sys/event.h> 
     56#include <unistd.h> 
     57#endif 
     58 
    5359#include <libdaemon/dfork.h> 
    5460#include <libdaemon/dsignal.h> 
    5561#include <libdaemon/dlog.h> 
     
    691697 
    692698#endif 
    693699 
     700#ifdef HAVE_KQUEUE 
     701 
     702#define NUM_WATCHES 2 
     703 
     704static int kq = -1; 
     705static int kfds[NUM_WATCHES]; 
     706static int num_kfds = 0; 
     707 
     708static void add_kqueue_watch(const char *dir); 
     709 
     710static void add_kqueue_watches(void) { 
     711    int c = 0; 
     712 
     713#ifdef ENABLE_CHROOT 
     714    c = config.use_chroot; 
     715#endif 
     716 
     717    add_kqueue_watch(c ? "/" : AVAHI_CONFIG_DIR); 
     718    add_kqueue_watch(c ? "/services" : AVAHI_SERVICE_DIR); 
     719} 
     720 
     721static void add_kqueue_watch(const char *dir) { 
     722    int fd; 
     723    struct kevent ev; 
     724 
     725    if (kq < 0) 
     726        return; 
     727 
     728    if (num_kfds >= NUM_WATCHES) 
     729        return; 
     730 
     731    fd = open(dir, O_RDONLY); 
     732    if (fd < 0) 
     733        return; 
     734    EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, 
     735            NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_RENAME, 
     736            0, 0); 
     737    if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) { 
     738        close(fd); 
     739        return; 
     740    } 
     741 
     742    kfds[num_kfds++] = fd; 
     743} 
     744 
     745#endif 
     746 
    694747static void reload_config(void) { 
    695748 
    696749#ifdef HAVE_INOTIFY 
     
    698751    add_inotify_watches(); 
    699752#endif 
    700753 
     754#ifdef HAVE_KQUEUE 
     755    add_kqueue_watches(); 
     756#endif 
     757 
    701758#ifdef ENABLE_CHROOT 
    702759    static_service_load(config.use_chroot); 
    703760    static_hosts_load(config.use_chroot); 
     
    746803 
    747804#endif 
    748805 
     806#ifdef HAVE_KQUEUE 
     807 
     808static void kqueue_callback(AvahiWatch *watch, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) { 
     809    struct kevent ev; 
     810    struct timespec nullts = { 0, 0 }; 
     811    int res; 
     812 
     813    assert(fd == kq); 
     814    assert(watch); 
     815 
     816    res = kevent(kq, NULL, 0, &ev, 1, &nullts); 
     817 
     818    if (res > 0) { 
     819        /* Sleep for a half-second to avoid potential races 
     820         * during install/uninstall. */ 
     821        usleep(500000); 
     822        avahi_log_info("Files changed, reloading."); 
     823        reload_config(); 
     824    } else { 
     825        avahi_log_error("Failed to read kqueue event: %s", avahi_strerror(errno)); 
     826    } 
     827} 
     828 
     829#endif 
     830 
    749831static void signal_callback(AvahiWatch *watch, AVAHI_GCC_UNUSED int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) { 
    750832    int sig; 
    751833    const AvahiPoll *poll_api; 
     
    801883#ifdef HAVE_INOTIFY 
    802884    AvahiWatch *inotify_watch = NULL; 
    803885#endif 
     886#ifdef HAVE_KQUEUE 
     887    int i; 
     888    AvahiWatch *kqueue_watch = NULL; 
     889#endif 
    804890 
    805891    assert(c); 
    806892 
     
    876962    } 
    877963#endif 
    878964 
     965#ifdef HAVE_KQUEUE 
     966    if ((kq = kqueue()) < 0) 
     967        avahi_log_warn( "Failed to initialize kqueue: %s", strerror(errno)); 
     968    else { 
     969        add_kqueue_watches(); 
     970 
     971        if (!(kqueue_watch = poll_api->watch_new(poll_api, kq, AVAHI_WATCH_IN, kqueue_callback, NULL))) { 
     972            avahi_log_error( "Failed to create kqueue watcher"); 
     973            goto finish; 
     974        } 
     975    } 
     976#endif 
     977 
    879978    load_resolv_conf(); 
    880979#ifdef ENABLE_CHROOT 
    881980    static_service_load(config.use_chroot); 
     
    9441043        poll_api->watch_free(inotify_watch); 
    9451044    if (inotify_fd >= 0) 
    9461045        close(inotify_fd); 
     1046#endif 
     1047 
     1048#ifdef HAVE_KQUEUE 
     1049    if (kqueue_watch) 
     1050    poll_api->watch_free(kqueue_watch); 
     1051    if (kq >= 0) 
     1052    close(kq); 
     1053    for (i = 0; i < num_kfds; i++) { 
     1054    if (kfds[i] >= 0) 
     1055        close(kfds[i]); 
     1056    } 
    9471057#endif 
    9481058     
    9491059    if (simple_poll_api) {