[telepathy-mission-control/master] McdDispatcher: make client introspection robust against clients disappearing or otherwise misbehaving
Simon McVittie
simon.mcvittie at collabora.co.uk
Tue May 12 10:38:29 PDT 2009
---
src/mcd-dispatcher.c | 93 +++++++++++++++++++++++++++++++++++++++----------
1 files changed, 74 insertions(+), 19 deletions(-)
diff --git a/src/mcd-dispatcher.c b/src/mcd-dispatcher.c
index 9aaa9ac..471a285 100644
--- a/src/mcd-dispatcher.c
+++ b/src/mcd-dispatcher.c
@@ -1722,7 +1722,18 @@ get_bypass_approval_cb (TpProxy *proxy,
gpointer user_data,
GObject *weak_object)
{
- McdClient *client = user_data;
+ McdDispatcher *self = MCD_DISPATCHER (weak_object);
+ const gchar *bus_name = tp_proxy_get_bus_name (proxy);
+ McdClient *client;
+
+ client = g_hash_table_lookup (self->priv->clients, bus_name);
+
+ if (G_UNLIKELY (client == NULL))
+ {
+ DEBUG ("Client %s vanished while we were getting BypassApproval",
+ bus_name);
+ return;
+ }
if (error != NULL)
{
@@ -1746,15 +1757,27 @@ get_bypass_approval_cb (TpProxy *proxy,
static void
get_channel_filter_cb (TpProxy *proxy,
- const GValue *out_Value,
+ const GValue *value,
const GError *error,
gpointer user_data,
GObject *weak_object)
{
- GList **client_filters = user_data;
+ McdDispatcher *self = MCD_DISPATCHER (weak_object);
+ McdClient *client;
+ const gchar *bus_name = tp_proxy_get_bus_name (proxy);
+ GList **client_filters;
GPtrArray *filters;
guint i;
+ client = g_hash_table_lookup (self->priv->clients, bus_name);
+
+ if (G_UNLIKELY (client == NULL))
+ {
+ DEBUG ("Client %s vanished while we were getting its Client filters",
+ bus_name);
+ return;
+ }
+
if (error != NULL)
{
DEBUG ("error getting a filter list for client %s: %s #%d: %s",
@@ -1763,9 +1786,32 @@ get_channel_filter_cb (TpProxy *proxy,
return;
}
- /* FIXME: if the GValue isn't of the right type, don't crash */
+ if (!G_VALUE_HOLDS (value, TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST))
+ {
+ DEBUG ("wrong type for filter property on client %s: %s",
+ tp_proxy_get_object_path (proxy), G_VALUE_TYPE_NAME (value));
+ return;
+ }
- filters = g_value_get_boxed (out_Value);
+ switch (GPOINTER_TO_UINT (user_data))
+ {
+ case MCD_CLIENT_OBSERVER:
+ client_filters = &client->observer_filters;
+ break;
+
+ case MCD_CLIENT_APPROVER:
+ client_filters = &client->approver_filters;
+ break;
+
+ case MCD_CLIENT_HANDLER:
+ client_filters = &client->handler_filters;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ filters = g_value_get_boxed (value);
for (i = 0 ; i < filters->len ; i++)
{
@@ -1856,27 +1902,36 @@ get_interfaces_cb (TpProxy *proxy,
{
McdDispatcher *self = MCD_DISPATCHER (weak_object);
/* McdDispatcherPrivate *priv = MCD_DISPATCHER_PRIV (self); */
- McdClient *client = user_data;
+ McdClient *client;
gchar **arr;
+ const gchar *bus_name = tp_proxy_get_bus_name (proxy);
if (error != NULL)
{
DEBUG ("Error getting Interfaces for Client %s, assuming none: "
- "%s %d %s", client->name, g_quark_to_string (error->domain),
- error->code, error->message);
- arr = NULL;
+ "%s %d %s", bus_name,
+ g_quark_to_string (error->domain), error->code, error->message);
+ return;
}
- else if (!G_VALUE_HOLDS (out_Value, G_TYPE_STRV))
+
+ if (!G_VALUE_HOLDS (out_Value, G_TYPE_STRV))
{
DEBUG ("Wrong type getting Interfaces for Client %s, assuming none: "
- "%s", client->name, G_VALUE_TYPE_NAME (out_Value));
- arr = NULL;
+ "%s", bus_name, G_VALUE_TYPE_NAME (out_Value));
+ return;
}
- else
+
+ client = g_hash_table_lookup (self->priv->clients, bus_name);
+
+ if (G_UNLIKELY (client == NULL))
{
- arr = g_value_get_boxed (out_Value);
+ DEBUG ("Client %s vanished while we were getting its interfaces",
+ bus_name);
+ return;
}
+ arr = g_value_get_boxed (out_Value);
+
while (arr != NULL && *arr != NULL)
{
if (strcmp (*arr, MC_IFACE_CLIENT_APPROVER) == 0)
@@ -1900,25 +1955,25 @@ get_interfaces_cb (TpProxy *proxy,
tp_cli_dbus_properties_call_get
(client->proxy, -1, MC_IFACE_CLIENT_APPROVER,
"ApproverChannelFilter", get_channel_filter_cb,
- &client->approver_filters, NULL, G_OBJECT (self));
+ GUINT_TO_POINTER (MCD_CLIENT_APPROVER), NULL, G_OBJECT (self));
}
if (client->interfaces & MCD_CLIENT_HANDLER)
{
tp_cli_dbus_properties_call_get
(client->proxy, -1, MC_IFACE_CLIENT_HANDLER,
"BypassApproval", get_bypass_approval_cb,
- client, NULL, G_OBJECT (self));
+ NULL, NULL, G_OBJECT (self));
tp_cli_dbus_properties_call_get
(client->proxy, -1, MC_IFACE_CLIENT_HANDLER,
"HandlerChannelFilter", get_channel_filter_cb,
- &client->handler_filters, NULL, G_OBJECT (self));
+ GUINT_TO_POINTER (MCD_CLIENT_HANDLER), NULL, G_OBJECT (self));
}
if (client->interfaces & MCD_CLIENT_OBSERVER)
{
tp_cli_dbus_properties_call_get
(client->proxy, -1, MC_IFACE_CLIENT_OBSERVER,
"ObserverChannelFilter", get_channel_filter_cb,
- &client->observer_filters, NULL, G_OBJECT (self));
+ GUINT_TO_POINTER (MCD_CLIENT_OBSERVER), NULL, G_OBJECT (self));
}
}
@@ -2104,7 +2159,7 @@ create_mcd_client (McdDispatcher *self,
{
DEBUG ("No .client file for %s. Ask on D-Bus.", name);
tp_cli_dbus_properties_call_get (client->proxy, -1,
- MC_IFACE_CLIENT, "Interfaces", get_interfaces_cb, client,
+ MC_IFACE_CLIENT, "Interfaces", get_interfaces_cb, NULL,
NULL, G_OBJECT (self));
}
else
--
1.5.6.5
More information about the telepathy-commits
mailing list