pulse-server: handle server started and stopped events

When a server is started, try to publish the pending services.
When a server is stopped, republish the services.

This makes it possible to load and unload the tcp protocol after loading
the zeroconf publish module and it will do the right thing.
This commit is contained in:
Wim Taymans 2022-11-17 18:36:47 +01:00
parent a11612bdad
commit 3085e312b6

View file

@ -85,6 +85,7 @@ struct service {
struct pw_properties *props;
char service_name[AVAHI_LABEL_MAX];
unsigned published:1;
};
struct module_zeroconf_publish_data {
@ -95,6 +96,7 @@ struct module_zeroconf_publish_data {
struct spa_hook core_listener;
struct spa_hook manager_listener;
struct spa_hook impl_listener;
AvahiPoll *avahi_poll;
AvahiClient *client;
@ -151,6 +153,7 @@ static void unpublish_service(struct service *s)
{
spa_list_remove(&s->link);
spa_list_append(&s->userdata->pending, &s->link);
s->published = false;
}
static void unpublish_all_services(struct module_zeroconf_publish_data *d)
@ -315,6 +318,11 @@ static void service_entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupStat
struct service *s = userdata;
spa_assert(s);
if (!s->published) {
pw_log_info("cancel unpublished service: %s", s->service_name);
clear_entry_group(s);
return;
}
switch (state) {
case AVAHI_ENTRY_GROUP_ESTABLISHED:
@ -418,15 +426,18 @@ static void publish_service(struct service *s)
if (find_port(s, &proto, &port) < 0)
return;
pw_log_debug("found proto:%d port:%d", proto, port);
if (!d->client || avahi_client_get_state(d->client) != AVAHI_CLIENT_S_RUNNING)
return;
s->published = true;
if (!s->entry_group) {
s->entry_group = avahi_entry_group_new(d->client, service_entry_group_callback, s);
if (s->entry_group == NULL) {
pw_log_error("avahi_entry_group_new(): %s",
avahi_strerror(avahi_client_errno(d->client)));
return;
goto error;
}
} else {
avahi_entry_group_reset(s->entry_group);
@ -447,7 +458,7 @@ static void publish_service(struct service *s)
s->txt) < 0) {
pw_log_error("avahi_entry_group_add_service_strlst(): %s",
avahi_strerror(avahi_client_errno(d->client)));
return;
goto error;
}
if (avahi_entry_group_add_service_subtype(
@ -462,7 +473,7 @@ static void publish_service(struct service *s)
pw_log_error("avahi_entry_group_add_service_subtype(): %s",
avahi_strerror(avahi_client_errno(d->client)));
return;
goto error;
}
if (!s->is_sink && s->subtype != SUBTYPE_MONITOR) {
@ -476,20 +487,25 @@ static void publish_service(struct service *s)
SERVICE_SUBTYPE_SOURCE_NON_MONITOR) < 0) {
pw_log_error("avahi_entry_group_add_service_subtype(): %s",
avahi_strerror(avahi_client_errno(d->client)));
return;
goto error;
}
}
if (avahi_entry_group_commit(s->entry_group) < 0) {
pw_log_error("avahi_entry_group_commit(): %s",
avahi_strerror(avahi_client_errno(d->client)));
return;
goto error;
}
spa_list_remove(&s->link);
spa_list_append(&d->published, &s->link);
pw_log_info("created service: %s", s->service_name);
return;
error:
s->published = false;
return;
}
static void publish_pending(struct module_zeroconf_publish_data *data)
@ -598,6 +614,28 @@ static const struct pw_manager_events manager_events = {
.removed = manager_removed,
};
static void impl_server_started(void *data, struct server *server)
{
struct module_zeroconf_publish_data *d = data;
pw_log_info("a new server is started, try publish");
publish_pending(d);
}
static void impl_server_stopped(void *data, struct server *server)
{
struct module_zeroconf_publish_data *d = data;
pw_log_info("a server stopped, try republish");
unpublish_all_services(d);
publish_pending(d);
}
static const struct impl_events impl_events = {
VERSION_IMPL_EVENTS,
.server_started = impl_server_started,
.server_stopped = impl_server_stopped,
};
static int module_zeroconf_publish_load(struct client *client, struct module *module)
{
struct module_zeroconf_publish_data *data = module->user_data;
@ -634,6 +672,8 @@ static int module_zeroconf_publish_load(struct client *client, struct module *mo
pw_manager_add_listener(data->manager, &data->manager_listener,
&manager_events, data);
impl_add_listener(module->impl, &data->impl_listener, &impl_events, data);
return 0;
}
@ -642,6 +682,8 @@ static int module_zeroconf_publish_unload(struct module *module)
struct module_zeroconf_publish_data *d = module->user_data;
struct service *s;
spa_hook_remove(&d->impl_listener);
unpublish_all_services(d);
spa_list_consume(s, &d->pending, link)