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