/* Could be called from any thread, so it could be called after client_unref() * has started finalising the #Client. Avoid that by looking up the #Client * atomically. */ static void on_connection_disconnected (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data) { guint watcher_id = GPOINTER_TO_UINT (user_data); Client *client = NULL; client = dup_client (watcher_id); if (client == NULL) return; if (client->name_owner_changed_subscription_id > 0) g_dbus_connection_signal_unsubscribe (client->connection, client->name_owner_changed_subscription_id); if (client->disconnected_signal_handler_id > 0) g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); g_object_unref (client->connection); client->disconnected_signal_handler_id = 0; client->name_owner_changed_subscription_id = 0; client->connection = NULL; call_vanished_handler (client, FALSE); client_unref (client); }
/* Will always be called from the thread which acquired client->main_context. */ static void on_name_owner_changed (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data) { guint watcher_id = GPOINTER_TO_UINT (user_data); Client *client = NULL; const gchar *name; const gchar *old_owner; const gchar *new_owner; client = dup_client (watcher_id); if (client == NULL) return; if (!client->initialized) goto out; if (g_strcmp0 (object_path, "/org/freedesktop/DBus") != 0 || g_strcmp0 (interface_name, "org.freedesktop.DBus") != 0 || g_strcmp0 (sender_name, "org.freedesktop.DBus") != 0) goto out; g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner); /* we only care about a specific name */ if (g_strcmp0 (name, client->name) != 0) goto out; if ((old_owner != NULL && strlen (old_owner) > 0) && client->name_owner != NULL) { g_free (client->name_owner); client->name_owner = NULL; call_vanished_handler (client, FALSE); } if (new_owner != NULL && strlen (new_owner) > 0) { g_warn_if_fail (client->name_owner == NULL); g_free (client->name_owner); client->name_owner = g_strdup (new_owner); call_appeared_handler (client); } out: client_unref (client); }
static void start_service_by_name_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { Client *client = user_data; GVariant *result; result = NULL; result = g_dbus_connection_call_finish (client->connection, res, NULL); if (result != NULL) { guint32 start_service_result; g_variant_get (result, "(u)", &start_service_result); if (start_service_result == 1) /* DBUS_START_REPLY_SUCCESS */ { invoke_get_name_owner (client); } else if (start_service_result == 2) /* DBUS_START_REPLY_ALREADY_RUNNING */ { invoke_get_name_owner (client); } else { g_warning ("Unexpected reply %d from StartServiceByName() method", start_service_result); call_vanished_handler (client, FALSE); client->initialized = TRUE; } } else { /* Errors are not unexpected; the bus will reply e.g. * * org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.Epiphany2 * was not provided by any .service files * * This doesn't mean that the name doesn't have an owner, just * that it's not provided by a .service file. So proceed to * invoke GetNameOwner(). */ invoke_get_name_owner (client); } if (result != NULL) g_variant_unref (result); client_unref (client); }
static void connection_get_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { Client *client = user_data; client->connection = g_bus_get_finish (res, NULL); if (client->connection == NULL) { call_vanished_handler (client, FALSE); goto out; } has_connection (client); out: client_unref (client); }
static void on_connection_disconnected (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error, gpointer user_data) { Client *client = user_data; if (client->name_owner_changed_subscription_id > 0) g_dbus_connection_signal_unsubscribe (client->connection, client->name_owner_changed_subscription_id); if (client->disconnected_signal_handler_id > 0) g_signal_handler_disconnect (client->connection, client->disconnected_signal_handler_id); g_object_unref (client->connection); client->disconnected_signal_handler_id = 0; client->name_owner_changed_subscription_id = 0; client->connection = NULL; call_vanished_handler (client, FALSE); }
static void get_name_owner_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { Client *client = user_data; GVariant *result; const char *name_owner; name_owner = NULL; result = NULL; result = g_dbus_connection_call_finish (client->connection, res, NULL); if (result != NULL) { g_variant_get (result, "(&s)", &name_owner); } if (name_owner != NULL) { g_warn_if_fail (client->name_owner == NULL); client->name_owner = g_strdup (name_owner); call_appeared_handler (client); } else { call_vanished_handler (client, FALSE); } client->initialized = TRUE; if (result != NULL) g_variant_unref (result); client_unref (client); }