| = 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. | |
| == Example == | |
| 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); | |
| } |