Skip to content
Snippets Groups Projects
Commit 340b52fb authored by George Kiagiadakis's avatar George Kiagiadakis
Browse files

proxy: fix crash that happens when a client exits very quickly after starting

This is very easy to reproduce when the pipewire-alsa integration
is installed and you do 'arecord -l'; the alsa plugin connects and
disconnects again before the proxy is ready.

In this case we have to skip remote-global-added and we also have
to be careful with the references: the global-removed callback is
called earlier, so the core's reference to the proxy is gone and
the GTask is the only thing holding a reference to the proxy.
When we unref the GTask, the proxy is also unrefed, so we have
to keep an additional reference in order to avoid crashing
when accessing the hash table below.
parent ac53b116
No related branches found
No related tags found
No related merge requests found
......@@ -138,6 +138,7 @@ on_proxy_ready (GObject * obj, GAsyncResult * res, gpointer data)
if (!wp_proxy_augment_finish (proxy, res, &error)) {
g_warning ("Failed to augment WpProxy (%p): %s", obj, error->message);
return;
}
g_signal_emit (self, signals[SIGNAL_REMOTE_GLOBAL_ADDED],
......
......@@ -130,7 +130,9 @@ wp_proxy_find_quark_for_type (guint32 type)
static void
proxy_event_destroy (void *data)
{
WpProxy *self = WP_PROXY (data);
/* hold a reference to the proxy because unref-ing the tasks might
destroy the proxy, in case the core is no longer holding a reference */
g_autoptr (WpProxy) self = g_object_ref (WP_PROXY (data));
WpProxyPrivate *priv = wp_proxy_get_instance_private (self);
GHashTableIter iter;
GTask *task;
......@@ -144,7 +146,7 @@ proxy_event_destroy (void *data)
if (priv->task) {
g_task_return_new_error (priv->task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED,
"pipewire node proxy destroyed before finishing");
"pipewire proxy destroyed before finishing");
g_clear_object (&priv->task);
}
......@@ -152,7 +154,7 @@ proxy_event_destroy (void *data)
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &task)) {
g_task_return_new_error (task, WP_DOMAIN_LIBRARY,
WP_LIBRARY_ERROR_OPERATION_FAILED,
"pipewire node proxy destroyed before finishing");
"pipewire proxy destroyed before finishing");
g_hash_table_iter_remove (&iter);
}
}
......@@ -218,9 +220,9 @@ wp_proxy_finalize (GObject * object)
g_debug ("%s:%p destroyed (global %u; pw_proxy %p)",
G_OBJECT_TYPE_NAME (object), object, priv->global_id, priv->pw_proxy);
g_clear_pointer (&priv->pw_proxy, pw_proxy_destroy);
g_clear_object (&priv->task);
g_clear_pointer (&priv->global_props, wp_properties_unref);
g_clear_pointer (&priv->pw_proxy, pw_proxy_destroy);
g_weak_ref_clear (&priv->core);
g_clear_pointer (&priv->async_tasks, g_hash_table_unref);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment