+/* Runs in Avahi mainloop context */
+static void create_client(pa_mainloop_api *api PA_GCC_UNUSED, void *userdata) {
+ struct userdata *u = (struct userdata *) userdata;
+ int error;
+
+ /* create_client() and client_free() are called via defer events. If the
+ * two defer events are created very quickly one after another, we can't
+ * assume that the defer event that runs create_client() will be dispatched
+ * before the defer event that runs client_free() (at the time of writing,
+ * pa_mainloop actually always dispatches queued defer events in reverse
+ * creation order). For that reason we must be prepared for the case where
+ * client_free() has already been called. */
+ if (u->client_freed)
+ return;
+
+ pa_thread_mq_install(&u->thread_mq);
+
+ if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
+ pa_log("avahi_client_new() failed: %s", avahi_strerror(error));
+ goto fail;
+ }
+
+ pa_log_debug("Started Avahi threaded mainloop");
+
+ return;
+
+fail:
+ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->msg), AVAHI_MESSAGE_SHUTDOWN_START, u, 0, NULL, NULL);
+}
+