[epiphany] uri-tester: Track DBus peers and unregister object when disposing



commit d13928c5c8d20ddf64c17b10f9d656072c51fb82
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Tue Nov 1 20:00:28 2016 -0500

    uri-tester: Track DBus peers and unregister object when disposing
    
    Speculative fix for a reported crasher

 embed/ephy-embed-shell.c |    6 +++-
 embed/ephy-uri-tester.c  |   63 ++++++++++++++++++++++++++++++++++++++++++++-
 embed/ephy-uri-tester.h  |    4 +-
 3 files changed, 67 insertions(+), 6 deletions(-)
---
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 5f71feb..f40fffa 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -607,10 +607,12 @@ new_connection_cb (GDBusServer     *server,
                    EphyEmbedShell  *shell)
 {
   EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
-  EphyWebExtensionProxy *extension = ephy_web_extension_proxy_new (connection);
+  EphyWebExtensionProxy *extension;
+
+  extension = ephy_web_extension_proxy_new (connection);
   ephy_embed_shell_watch_web_extension (shell, extension);
 
-  ephy_uri_tester_register_dbus_object (priv->uri_tester, connection);
+  ephy_uri_tester_handle_new_dbus_connection (priv->uri_tester, connection);
 
   g_signal_connect_object (extension, "page-created",
                            G_CALLBACK (web_extension_page_created), shell, 0);
diff --git a/embed/ephy-uri-tester.c b/embed/ephy-uri-tester.c
index 37604ff..9e1c01b 100644
--- a/embed/ephy-uri-tester.c
+++ b/embed/ephy-uri-tester.c
@@ -79,6 +79,8 @@ struct _EphyUriTester {
 
   HTTPSEverywhereContext *https_everywhere_context;
   GList *deferred_requests;
+
+  GList *dbus_peers;
 };
 
 enum {
@@ -880,6 +882,43 @@ ephy_uri_tester_rewrite_uri (EphyUriTester *tester,
   return result;
 }
 
+typedef struct {
+  EphyUriTester *tester;
+  GDBusConnection *connection;
+  guint registration_id;
+} DBusPeerInfo;
+
+static DBusPeerInfo *
+dbus_peer_info_new (EphyUriTester   *tester,
+                    GDBusConnection *connection,
+                    guint            registration_id)
+{
+  DBusPeerInfo *peer = g_slice_new (DBusPeerInfo);
+  peer->tester = tester;
+  peer->connection = g_object_ref (connection);
+  peer->registration_id = registration_id;
+  return peer;
+}
+
+static void
+dbus_peer_info_free (DBusPeerInfo *peer)
+{
+  g_signal_handlers_disconnect_by_data (peer->connection, peer);
+
+  g_object_unref (peer->connection);
+  g_slice_free (DBusPeerInfo, peer);
+}
+
+static void
+dbus_connection_closed_cb (GDBusConnection *connection,
+                           gboolean         remote_peer_vanished,
+                           GError          *error,
+                           DBusPeerInfo    *peer)
+{
+  peer->tester->dbus_peers = g_list_remove (peer->tester->dbus_peers, peer);
+  dbus_peer_info_free (peer);
+}
+
 static void
 ephy_uri_tester_return_response (EphyUriTester         *tester,
                                  const char            *request_uri,
@@ -943,10 +982,11 @@ static const GDBusInterfaceVTable interface_vtable = {
 };
 
 void
-ephy_uri_tester_register_dbus_object (EphyUriTester   *tester,
-                                      GDBusConnection *connection)
+ephy_uri_tester_handle_new_dbus_connection (EphyUriTester   *tester,
+                                            GDBusConnection *connection)
 {
   static GDBusNodeInfo *introspection_data = NULL;
+  DBusPeerInfo *peer;
   guint registration_id;
   GError *error = NULL;
 
@@ -966,6 +1006,12 @@ ephy_uri_tester_register_dbus_object (EphyUriTester   *tester,
     g_error_free (error);
     return;
   }
+
+  peer = dbus_peer_info_new (tester, connection, registration_id);
+  tester->dbus_peers = g_list_append (tester->dbus_peers, peer);
+
+  g_signal_connect (connection, "closed",
+                    G_CALLBACK (dbus_connection_closed_cb), peer);
 }
 
 static void
@@ -1141,6 +1187,13 @@ ephy_uri_tester_set_property (GObject      *object,
 }
 
 static void
+unregister_dbus_object (DBusPeerInfo  *peer,
+                        EphyUriTester *tester)
+{
+  g_dbus_connection_unregister_object (peer->connection, peer->registration_id);
+}
+
+static void
 ephy_uri_tester_dispose (GObject *object)
 {
   EphyUriTester *tester = EPHY_URI_TESTER (object);
@@ -1152,6 +1205,12 @@ ephy_uri_tester_dispose (GObject *object)
     g_clear_object (&tester->cancellable);
   }
 
+  if (tester->dbus_peers) {
+    g_list_foreach (tester->dbus_peers, (GFunc)unregister_dbus_object, tester);
+    g_list_free_full (tester->dbus_peers, (GDestroyNotify)dbus_peer_info_free);
+    tester->dbus_peers = NULL;
+  }
+
   G_OBJECT_CLASS (ephy_uri_tester_parent_class)->dispose (object);
 }
 
diff --git a/embed/ephy-uri-tester.h b/embed/ephy-uri-tester.h
index 0791721..8b3e19d 100644
--- a/embed/ephy-uri-tester.h
+++ b/embed/ephy-uri-tester.h
@@ -30,7 +30,7 @@ G_DECLARE_FINAL_TYPE (EphyUriTester, ephy_uri_tester, EPHY, URI_TESTER, GObject)
 
 EphyUriTester *ephy_uri_tester_new                  (void);
 
-void           ephy_uri_tester_register_dbus_object (EphyUriTester   *tester,
-                                                     GDBusConnection *connection);
+void           ephy_uri_tester_handle_new_dbus_connection (EphyUriTester   *tester,
+                                                           GDBusConnection *connection);
 
 G_END_DECLS


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