ArchiveOrangemail archive

Avahi ML


avahi.lists.freedesktop.org
(List home) (Recent threads) (87 other Freedesktop.org lists)

Subscription Options

  • RSS or Atom: Read-only subscription using a browser or aggregator. This is the recommended way if you don't need to send messages to the list. You can learn more about feed syndication and clients here.
  • Conventional: All messages are delivered to your mail address, and you can reply. To subscribe, send an email to the list's subscribe address with "subscribe" in the subject line, or visit the list's homepage here.
  • Low traffic list: less than 3 messages per day
  • This list contains about 2,239 messages, beginning Nov 2004
  • 0 messages added yesterday
Report the Spam
This button sends a spam report to the moderator. Please use it sparingly. For other removal requests, read this.
Are you sure? yes no

asynchronous resolving causes segfault

Ad
Jared Albers 1339469168Tue, 12 Jun 2012 02:46:08 +0000 (UTC)
I am using a ZeroconfResolver object that encapsulates an AvahiClient,
AvahiSimplePoll, and AvahiServiceResolver. The ZeroconfResolver has a
Resolve function that first instantiates the AvahiSimplePoll, then
AvahiClient, and finally the AvahiServiceResolver. At each
instantiation I am checking for errors before continuing to the next.
After the AvahiServiceResolver has been successfully created it calls
avahi_simple_poll_loop with the AvahiSimplePoll.

This whole process works great when done synchronously but fails with
segfaults when multiple ZeroconfResolvers are being used at the same
time asynchronously (i.e I have multiple threads creating their own
ZeroconfResolver objects). A trivial adaptation of the object that
reproduces the segfaults can be seen at [2] (may not produce a
segfault right away, but in my use case it happens frequently).

I understand that "out of the box" Avahi is not thread safe, but
according to my interpretation of [1] it is safe to have multiple
AvahiClient/AvahiPoll objects in the same process as long as they are
not 'accessed' from more than one thread. Each ZeroconfResolver has
its own set of Avahi objects that do not interact with each other
across thread boundaries.

The segfaults occur in seemingly random functions within the Avahi
library. In general they happen within the avahi_client_new or
avahi_service_resolver_new functions referencing dbus. Does the wiki
mean to imply that the 'creation' of AvahiClient/AvahiPoll objects is
also not thread safe?

-Jared

[1] http://avahi.org/wiki/RunningAvahiClientAsThr...
[2] See below:

#include <xdispatch/dispatch.h>
#include <cstdio>

#include <sys/types.h>
#include <netinet/in.h>

#include <avahi-client/lookup.h>
#include <avahi-client/client.h>
#include <avahi-client/publish.h>
#include <avahi-common/alternative.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
#include <avahi-common/timeval.h>

void resolve_reply(
   AvahiServiceResolver *r,
   AVAHI_GCC_UNUSED AvahiIfIndex interface,
   AVAHI_GCC_UNUSED AvahiProtocol protocol,
   AvahiResolverEvent event,
   const char *name,
   const char *type,
   const char *domain,
   const char *host_name,
   const AvahiAddress *address,
   uint16_t port,
   AvahiStringList *txt,
   AvahiLookupResultFlags flags,
   void * context) {

   assert(r);

   if (event == AVAHI_RESOLVER_FOUND)
     printf("resolve_reply(%s, %s, %s, %s)[FOUND]\n", name, type,
domain, host_name);

   avahi_service_resolver_free(
r);
   avahi_simple_poll_quit((AvahiSimplePoll*)context);
}


int main() {

 // Run until segfault
 while (true) {
   // Adding block to conccurent GCD queue (managed thread pool)
   xdispatch::global_queue().async(${
     char name[] = "AnHTTPServer";
     char domain[] = "local.";
     char type[] = "_http._tcp.";

     AvahiSimplePoll * simple_poll = NULL;
     if ((simple_poll = avahi_simple_poll_new())) {
       int error;
       AvahiClient * client = NULL;
       if ((client =
avahi_client_new(avahi_simple_poll_get(simple_poll),
AVAHI_CLIENT_NO_FAIL, NULL, NULL, &error))) {
         AvahiServiceResolver * resolver = NULL;
         if ((resolver = avahi_service_resolver_new(client,
AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, name, type, domain,
AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_NO_ADDRESS,
(AvahiServiceResolverCallback)resolve_reply, simple_poll))) {
             avahi_simple_poll_loop(simple_poll);
             printf("Exit Loop(%p)\n", simple_poll);
         } else {
           printf("Resolve(%s, %s, %s)[%s]\n", name, type, domain,
avahi_strerror(avahi_client_errno(client)));
         }
         avahi_client_free(client);
       } else {
         printf("avahi_client_new()[%s]\n", avahi_strerror(error));
       }
       avahi_simple_poll_free(simple_poll);
     } else {
       printf("avahi_simple_poll_new()[Failed]\n");
     }
   });
 }

 // Never reached
 return 0;
}
Home | About | Privacy