+static ConnectionData *
+new_connection (GDBusConnection *connection,
+ guint registration_id)
+{
+ ConnectionData *data;
+
+ data = g_slice_new0 (ConnectionData);
+ data->connection = g_object_ref (connection);
+ data->registration_id = registration_id;
+
+ return data;
+}
+
+static void
+free_connection (ConnectionData *data)
+{
+ if (data != NULL)
+ {
+ g_object_unref (data->connection);
+ g_slice_free (ConnectionData, data);
+ }
+}
+
+static gboolean
+add_connection_locked (GDBusInterfaceSkeleton *interface_,
+ GDBusConnection *connection,
+ GError **error)
+{
+ ConnectionData *data;
+ guint registration_id;
+ gboolean ret = FALSE;
+
+ if (interface_->priv->hooked_vtable == NULL)
+ {
+ /* Hook the vtable since we need to intercept method calls for
+ * ::g-authorize-method and for dispatching in thread vs
+ * context
+ *
+ * We need to wait until subclasses have had time to initialize
+ * properly before building the hooked_vtable, so we create it
+ * once at the last minute.
+ */
+ interface_->priv->hooked_vtable = g_memdup (g_dbus_interface_skeleton_get_vtable (interface_), sizeof (GDBusInterfaceVTable));
+ interface_->priv->hooked_vtable->method_call = skeleton_intercept_handle_method_call;
+ }
+
+ registration_id = g_dbus_connection_register_object (connection,
+ interface_->priv->object_path,
+ g_dbus_interface_skeleton_get_info (interface_),
+ interface_->priv->hooked_vtable,
+ interface_,
+ NULL, /* user_data_free_func */
+ error);
+
+ if (registration_id > 0)
+ {
+ data = new_connection (connection, registration_id);
+ interface_->priv->connections = g_slist_append (interface_->priv->connections, data);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+static void
+remove_connection_locked (GDBusInterfaceSkeleton *interface_,
+ GDBusConnection *connection)
+{
+ ConnectionData *data;
+ GSList *l;
+
+ /* Get the connection in the list and unregister ... */
+ for (l = interface_->priv->connections; l != NULL; l = l->next)
+ {
+ data = l->data;
+ if (data->connection == connection)
+ {
+ g_warn_if_fail (g_dbus_connection_unregister_object (data->connection, data->registration_id));
+ free_connection (data);
+ interface_->priv->connections = g_slist_delete_link (interface_->priv->connections, l);
+ /* we are guaranteed that the connection is only added once, so bail out early */
+ goto out;
+ }
+ }
+ out:
+ ;
+}
+
+static void
+set_object_path_locked (GDBusInterfaceSkeleton *interface_,
+ const gchar *object_path)
+{
+ if (g_strcmp0 (interface_->priv->object_path, object_path) != 0)
+ {
+ g_free (interface_->priv->object_path);
+ interface_->priv->object_path = g_strdup (object_path);
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+