Error: Failed to load processor TracNav
No macro or processor named 'TracNav' found

Running the Avahi Client as a Thread

avahi-client does not do access locking out-of-the-box. An AvahiClient/AvahiPoll instance may be used in a multithreaded application as long as it is accessed from a single thread only. You can even run multiple AvahiClient/AvahiPoll instances in the same process, with one event loop thread for each. However, as soon as you want to access an AvahiClient/AvahiPoll object from more than one thread you must add proper locking support with a mutex.

Applications that do not have a proper event loop might need to schedule AvahiClient/AvahiPoll in its own thread. Avahi 0.6.4 has basic support for this kind of operation, using the new AvahiThreadedPoll object.

AvahiThreadedPoll is similar to an AvahiSimplePoll, with the difference that the main loop is run in its own helper thread. After creation of the object (avahi_threaded_poll_new()), you may get the associated AvahiPoll object using avahi_threaded_poll_get()) for passing it to avahi_client_new(). After setting up everything, you should be ready to start the main loop in its own thread. To do that just call avahi_threaded_poll_start(). To shut down the main loop, you may call avahi_threaded_poll_stop(), for freeing it afterwards call avahi_threaded_poll_free() on the object. In most programs this is all you need to do. Please remember that event loop callbacks are executed from the helper thread, hence you might need to do your own locking if you want to pass data from it to some other thread.

It is not safe to access the AvahiClient/AvahiPoll objects from anything but the helper thread after it is been started (such an access might be adding a new service or a new browser to the existing AvahiClient object from the main thread). If you need to do such things you need to lock those objects manually. AvahiThreadedPoll offers two functions to facilitate this: avahi_threaded_poll_lock() and avahi_threaded_poll_unlock(). This functions are not intended to be called from the helper thread itself, since the event loop callbacks are called with these locks held.

API Documentation for AvahiThreadedPoll is available from doxygen.

Putting it all together

This is an example how to integrate Avahi in an application that doesn't have a proper event loop, such as an FTP server. (This is untested pseudo-code!)

static AvahiClient *client = NULL;
static AvahiThreadedPoll *threaded_poll = NULL;

void zeroconf_setup(void) {
   /* Call this when the application starts up. */

   if (!(threaded_poll = avahi_threaded_poll_new())) {
     /* do something bad */
     return;
   }

   if (!(client = avahi_client_new(avahi_threaded_poll_get(threaded_poll), ...))) {
     /* do something bad */
     return;
   }

   /* create some browsers on the client object here, if you wish */
   if (!avahi_service_browser_new(client, .....)) {
     /* so something bad */
     return;
   }

   /* Finally, start the event loop thread */
   if (avahi_threaded_poll_start(threaded_poll) < 0) {
     /* do something bad */
     return;
   }
}

void zeroconf_shutdown(void) {
  /* Call this when the app shuts down */

  avahi_threaded_poll_stop(threaded_poll);
  avahi_client_free(client);
  avahi_threaded_poll_free(threaded_poll);
}

void zeroconf_foobar(void) {
   /* In case you need to attach or remove an object from the AvahiClient or 
      AvahiPoll objects in the main process thread, do it like this */

   /* First, block the event loop */
   avahi_thread_poll_lock(threaded_poll);
   
   /* Then, do your stuff */
   if (!avahi_service_browser_new(client, ....)) {
     /* do something bad */
   }

   /* Finally, unblock the event loop */
   avahi_thread_poll_unlock(threaded_poll);
}

Compatibility with Earlier Avahi Versions

Avahi 0.6, 0.6.1, 0.6.2 and 0.6.3 did not ship with AvahiThreadedPoll. You might want to place a copy if source:trunk/avahi-common/thread-watch.c and source:trunk/avahi-common/thread-watch.h in your application to make use of it and keep compatibility with these versions.