From 64affcaf499a2b5ba94a011fdb1ae1ae09391859 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <george.kiagiadakis@collabora.com> Date: Tue, 18 Jun 2019 10:21:58 +0300 Subject: [PATCH] proxy: maintain a weak ref to the core avoids criticals and crashes when the core is destroyed earlier --- lib/wp/proxy.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/wp/proxy.c b/lib/wp/proxy.c index feb26127..7815f701 100644 --- a/lib/wp/proxy.c +++ b/lib/wp/proxy.c @@ -14,7 +14,7 @@ typedef struct _WpProxyPrivate WpProxyPrivate; struct _WpProxyPrivate { /* The core */ - WpCore *core; + GWeakRef core; /* The proxy */ struct pw_proxy *proxy; @@ -42,12 +42,14 @@ static void proxy_event_destroy (void *data) { WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(data)); + g_autoptr (WpCore) core = g_weak_ref_get (&self->core); /* Set the proxy to NULL */ self->proxy = NULL; /* Remove the proxy from core */ - wp_core_remove_global (self->core, WP_GLOBAL_PROXY, data); + if (core) + wp_core_remove_global (core, WP_GLOBAL_PROXY, data); } static void @@ -77,16 +79,18 @@ static void wp_proxy_finalize (GObject * object) { WpProxyPrivate *self = wp_proxy_get_instance_private (WP_PROXY(object)); - + /* Remove the listener */ spa_hook_remove (&self->listener); - + /* Destroy the proxy */ if (self->proxy) { pw_proxy_destroy (self->proxy); self->proxy = NULL; } + g_weak_ref_clear (&self->core); + G_OBJECT_CLASS (wp_proxy_parent_class)->finalize (object); } @@ -98,7 +102,7 @@ wp_proxy_set_property (GObject * object, guint property_id, switch (property_id) { case PROP_CORE: - self->core = g_value_get_pointer (value); + g_weak_ref_set (&self->core, g_value_get_object (value)); break; case PROP_PROXY: self->proxy = g_value_get_pointer (value); @@ -117,7 +121,7 @@ wp_proxy_get_property (GObject * object, guint property_id, GValue * value, switch (property_id) { case PROP_CORE: - g_value_set_pointer (value, self->core); + g_value_take_object (value, g_weak_ref_get (&self->core)); break; case PROP_PROXY: g_value_set_pointer (value, self->proxy); @@ -165,6 +169,8 @@ wp_proxy_async_initable_init (gpointer iface, gpointer iface_data) static void wp_proxy_init (WpProxy * self) { + WpProxyPrivate *priv = wp_proxy_get_instance_private (self); + g_weak_ref_init (&priv->core, NULL); } static void @@ -178,7 +184,8 @@ wp_proxy_class_init (WpProxyClass * klass) /* Install the properties */ g_object_class_install_property (object_class, PROP_CORE, - g_param_spec_pointer ("core", "core", "The wireplumber core", + g_param_spec_object ("core", "core", "The wireplumber core", + WP_TYPE_CORE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_PROXY, g_param_spec_pointer ("pw-proxy", "pw-proxy", "The pipewire proxy", @@ -189,11 +196,15 @@ void wp_proxy_register(WpProxy * self) { WpProxyPrivate *priv; - + g_autoptr (WpCore) core = NULL; + g_return_if_fail (WP_IS_PROXY (self)); - + priv = wp_proxy_get_instance_private (self); - wp_core_register_global (priv->core, WP_GLOBAL_PROXY, g_object_ref (self), + core = g_weak_ref_get (&priv->core); + g_return_if_fail (core != NULL); + + wp_core_register_global (core, WP_GLOBAL_PROXY, g_object_ref (self), g_object_unref); } @@ -205,7 +216,7 @@ wp_proxy_get_core (WpProxy * self) g_return_val_if_fail (WP_IS_PROXY (self), NULL); priv = wp_proxy_get_instance_private (self); - return priv->core; + return g_weak_ref_get (&priv->core); } gpointer -- GitLab