diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2012-05-08 14:39:44 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2012-05-08 14:39:44 +0100 |
commit | d0de667ec276eaca115a00b0c7b0010488459ae9 (patch) | |
tree | 64e62826e595364e3dff40e315b8260276fdbc53 | |
parent | f34edd09cbde51e3bd8517bcdc93575b0a11a2cb (diff) |
Avoid race condition when disposing of app
When disposing of the VirtViewerApp, we free the hash table
containing the windows. This causes each window to be freed,
which in turn causes the visibility callback to be invoked.
This can then get NULL pointers from the self->priv->windows
usage.
Blank out priv->windows before unrefing the hashs and add
a check to ensure priv->windows is non-NULL.
-rw-r--r-- | src/virt-viewer-app.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c index 82149dc..b2f42ca 100644 --- a/src/virt-viewer-app.c +++ b/src/virt-viewer-app.c @@ -1254,9 +1254,13 @@ virt_viewer_app_dispose (GObject *object) VirtViewerAppPrivate *priv = self->priv; if (priv->windows) { - g_hash_table_unref(priv->windows); + GHashTable *tmp = priv->windows; + /* null-ify before unrefing, because we need + * to prevent callbacks using priv->windows + * while it is being disposed off. */ priv->windows = NULL; priv->main_window = NULL; + g_hash_table_unref(tmp); } if (priv->container) { @@ -1636,6 +1640,8 @@ window_update_menu_displays_cb(gpointer key G_GNUC_UNUSED, static void virt_viewer_app_update_menu_displays(VirtViewerApp *self) { + if (!self->priv->windows) + return; g_hash_table_foreach(self->priv->windows, window_update_menu_displays_cb, self); } |