[PATCH virt-viewer] spice: fix double unref of main channel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When doing unref() on a channel, channel-destroy signal may be emitted
during object dispose time, and it will attempt to unref() the channel
again likely leading to a crash.

It may be that spice-gtk should have a different/simpler object
life-cycle model, but it's also a good assumption to not take strong
references on the channels, but just keep a weak reference as the
session is really the channel life-cycle manager.

https://bugzilla.redhat.com/show_bug.cgi?id=797082
---
 src/virt-viewer-session-spice.c |   13 +++----------
 1 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index cb7e000..eacb6e6 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -111,8 +111,6 @@ virt_viewer_session_spice_dispose(GObject *obj)
     }
     if (spice->priv->audio)
         g_object_unref(spice->priv->audio);
-    if (spice->priv->main_channel)
-        g_object_unref(spice->priv->main_channel);
     if (spice->priv->main_window)
         g_object_unref(spice->priv->main_window);
 
@@ -386,16 +384,13 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
     g_object_get(channel, "channel-id", &id, NULL);
 
     if (SPICE_IS_MAIN_CHANNEL(channel)) {
-        if (self->priv->main_channel != NULL) {
-            /* FIXME: use telepathy-glib g_signal_connect_object to automatically disconnect.. */
+        if (self->priv->main_channel != NULL)
             g_signal_handlers_disconnect_by_func(self->priv->main_channel,
                                                  virt_viewer_session_spice_main_channel_event, self);
-            g_object_unref(self->priv->main_channel);
-        }
 
         g_signal_connect(channel, "channel-event",
                          G_CALLBACK(virt_viewer_session_spice_main_channel_event), self);
-        self->priv->main_channel = g_object_ref(channel);
+        self->priv->main_channel = SPICE_MAIN_CHANNEL(channel);
     }
 
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
@@ -439,10 +434,8 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
     g_object_get(channel, "channel-id", &id, NULL);
     if (SPICE_IS_MAIN_CHANNEL(channel)) {
         DEBUG_LOG("zap main channel");
-        if (channel == SPICE_CHANNEL(self->priv->main_channel)) {
-            g_object_unref(self->priv->main_channel);
+        if (channel == SPICE_CHANNEL(self->priv->main_channel))
             self->priv->main_channel = NULL;
-        }
     }
 
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
-- 
1.7.7.6


[Index of Archives]     [Linux Virtualization]     [KVM Development]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]     [Video 4 Linux]

  Powered by Linux