media-session: handle disconnect better

This commit is contained in:
Wim Taymans 2018-09-26 13:22:21 +02:00
parent 4e2855f6fb
commit b8fb7aeaad

View file

@ -171,7 +171,8 @@ static void *find_object(struct impl *impl, uint32_t id)
static void schedule_rescan(struct impl *impl)
{
pw_core_proxy_sync(impl->core_proxy, ++impl->seq);
if (impl->core_proxy)
pw_core_proxy_sync(impl->core_proxy, ++impl->seq);
}
static void remove_idle_timeout(struct session *sess)
@ -216,7 +217,8 @@ static void add_idle_timeout(struct session *sess)
static int unlink_session_dsp(struct impl *impl, struct session *session)
{
pw_core_proxy_destroy(impl->core_proxy, (struct pw_proxy*)session->link);
if (impl->core_proxy)
pw_core_proxy_destroy(impl->core_proxy, (struct pw_proxy*)session->link);
session->link = NULL;
return 0;
}
@ -330,11 +332,32 @@ static const struct pw_node_proxy_events node_events = {
.info = node_event_info,
};
static void remove_session(struct impl *impl, struct session *sess)
{
struct node *n, *t;
pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id);
remove_idle_timeout(sess);
spa_list_for_each_safe(n, t, &sess->node_list, session_link) {
n->session = NULL;
spa_list_remove(&n->session_link);
}
if (sess->dsp && impl->core_proxy) {
pw_log_debug(NAME " %p: destroy dsp %p", impl, sess->dsp->obj.proxy);
pw_core_proxy_destroy(impl->core_proxy, sess->dsp->obj.proxy);
}
spa_list_remove(&sess->l);
free(sess);
}
static void node_proxy_destroy(void *data)
{
struct node *n = data;
struct impl *impl = n->obj.impl;
pw_log_debug(NAME " %p: proxy destroy node %d", n->obj.impl, n->obj.id);
pw_log_debug(NAME " %p: proxy destroy node %d", impl, n->obj.id);
spa_list_remove(&n->l);
if (n->info)
@ -343,6 +366,16 @@ static void node_proxy_destroy(void *data)
spa_list_remove(&n->session_link);
n->session = NULL;
}
if (n->manager) {
switch (n->type) {
case NODE_TYPE_DSP:
n->manager->dsp = NULL;
break;
case NODE_TYPE_DEVICE:
remove_session(impl, n->manager);
break;
}
}
}
static const struct pw_proxy_events node_proxy_events = {
@ -571,26 +604,6 @@ registry_global(void *data,uint32_t id, uint32_t parent_id,
schedule_rescan(impl);
}
static void remove_session(struct impl *impl, struct session *sess)
{
struct node *n, *t;
pw_log_debug(NAME " %p: remove session '%d'", impl, sess->id);
remove_idle_timeout(sess);
spa_list_for_each_safe(n, t, &sess->node_list, session_link) {
n->session = NULL;
spa_list_remove(&n->session_link);
}
if (sess->dsp) {
pw_log_debug(NAME " %p: destroy dsp", impl);
pw_core_proxy_destroy(impl->core_proxy, sess->dsp->obj.proxy);
}
spa_list_remove(&sess->l);
free(sess);
}
static void
registry_global_remove(void *data, uint32_t id)
{
@ -933,6 +946,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
break;
case PW_REMOTE_STATE_CONNECTED:
pw_log_info(NAME" %p: connected", impl);
impl->core_proxy = pw_remote_get_core_proxy(impl->remote);
impl->registry_proxy = pw_core_proxy_get_registry(impl->core_proxy,
PW_TYPE_INTERFACE_Registry,
@ -943,6 +957,13 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
schedule_rescan(impl);
break;
case PW_REMOTE_STATE_UNCONNECTED:
pw_log_info(NAME" %p: disconnected", impl);
impl->core_proxy = NULL;
impl->registry_proxy = NULL;
pw_main_loop_quit(impl->loop);
break;
default:
printf("remote state: \"%s\"\n", pw_remote_state_as_string(state));
break;