/* ---------------------------------------------------------------------------------------------------- */
+/* Convenience function to check if @registration_id (if not zero) or
+ * @subtree_registration_id (if not zero) has been unregistered. If
+ * so, returns %TRUE.
+ *
+ * Caller must *not* hold lock.
+ */
+static gboolean
+has_object_been_unregistered (GDBusConnection *connection,
+ guint registration_id,
+ guint subtree_registration_id)
+{
+ gboolean ret;
+
+ g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE);
+
+ ret = FALSE;
+
+ CONNECTION_LOCK (connection);
+ if (registration_id != 0 && g_hash_table_lookup (connection->priv->map_id_to_ei,
+ GUINT_TO_POINTER (registration_id)) == NULL)
+ {
+ ret = TRUE;
+ }
+ else if (subtree_registration_id != 0 && g_hash_table_lookup (connection->priv->map_id_to_es,
+ GUINT_TO_POINTER (subtree_registration_id)) == NULL)
+ {
+ ret = TRUE;
+ }
+ CONNECTION_UNLOCK (connection);
+
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
typedef struct
{
GDBusConnection *connection;
GDBusMessage *message;
gpointer user_data;
- const char *property_name;
+ const gchar *property_name;
const GDBusInterfaceVTable *vtable;
const GDBusInterfaceInfo *interface_info;
const GDBusPropertyInfo *property_info;
+ guint registration_id;
+ guint subtree_registration_id;
} PropertyData;
static void
GError *error;
GDBusMessage *reply;
+ if (has_object_been_unregistered (data->connection,
+ data->registration_id,
+ data->subtree_registration_id))
+ {
+ reply = g_dbus_message_new_method_error (data->message,
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ _("No such interface `org.freedesktop.DBus.Properties' on object at path %s"),
+ g_dbus_message_get_path (data->message));
+ g_dbus_connection_send_message (data->connection, reply, NULL, NULL);
+ g_object_unref (reply);
+ goto out;
+ }
+
error = NULL;
value = data->vtable->get_property (data->connection,
g_dbus_message_get_sender (data->message),
else
{
gchar *dbus_error_name;
-
g_assert (error != NULL);
-
dbus_error_name = g_dbus_error_encode_gerror (error);
reply = g_dbus_message_new_method_error_literal (data->message,
dbus_error_name,
g_object_unref (reply);
}
+ out:
return FALSE;
}
static gboolean
validate_and_maybe_schedule_property_getset (GDBusConnection *connection,
GDBusMessage *message,
+ guint registration_id,
+ guint subtree_registration_id,
gboolean is_get,
const GDBusInterfaceInfo *introspection_data,
const GDBusInterfaceVTable *vtable,
property_data->vtable = vtable;
property_data->interface_info = introspection_data;
property_data->property_info = property_info;
+ property_data->registration_id = registration_id;
+ property_data->subtree_registration_id = subtree_registration_id;
idle_source = g_idle_source_new ();
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
handled = validate_and_maybe_schedule_property_getset (eo->connection,
message,
+ ei->id,
+ 0,
is_get,
ei->introspection_data,
ei->vtable,
gpointer user_data;
const GDBusInterfaceVTable *vtable;
const GDBusInterfaceInfo *interface_info;
+ guint registration_id;
+ guint subtree_registration_id;
} PropertyGetAllData;
static void
GDBusMessage *reply;
guint n;
+ if (has_object_been_unregistered (data->connection,
+ data->registration_id,
+ data->subtree_registration_id))
+ {
+ reply = g_dbus_message_new_method_error (data->message,
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ _("No such interface `org.freedesktop.DBus.Properties' on object at path %s"),
+ g_dbus_message_get_path (data->message));
+ g_dbus_connection_send_message (data->connection, reply, NULL, NULL);
+ g_object_unref (reply);
+ goto out;
+ }
+
error = NULL;
/* TODO: Right now we never fail this call - we just omit values if
g_dbus_connection_send_message (data->connection, reply, NULL, NULL);
g_object_unref (reply);
+ out:
return FALSE;
}
static gboolean
validate_and_maybe_schedule_property_get_all (GDBusConnection *connection,
GDBusMessage *message,
+ guint registration_id,
+ guint subtree_registration_id,
const GDBusInterfaceInfo *introspection_data,
const GDBusInterfaceVTable *vtable,
GMainContext *main_context,
property_get_all_data->user_data = user_data;
property_get_all_data->vtable = vtable;
property_get_all_data->interface_info = introspection_data;
+ property_get_all_data->registration_id = registration_id;
+ property_get_all_data->subtree_registration_id = subtree_registration_id;
idle_source = g_idle_source_new ();
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
handled = validate_and_maybe_schedule_property_get_all (eo->connection,
message,
+ ei->id,
+ 0,
ei->introspection_data,
ei->vtable,
ei->context,
{
GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
GDBusInterfaceVTable *vtable;
+ guint registration_id;
+ guint subtree_registration_id;
vtable = g_object_get_data (G_OBJECT (invocation), "g-dbus-interface-vtable");
g_assert (vtable != NULL && vtable->method_call != NULL);
+ registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-registration-id"));
+ subtree_registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id"));
+
+ if (has_object_been_unregistered (g_dbus_method_invocation_get_connection (invocation),
+ registration_id,
+ subtree_registration_id))
+ {
+ GDBusMessage *reply;
+ reply = g_dbus_message_new_method_error (g_dbus_method_invocation_get_message (invocation),
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ _("No such interface `%s' on object at path %s"),
+ g_dbus_method_invocation_get_interface_name (invocation),
+ g_dbus_method_invocation_get_object_path (invocation));
+ g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), reply, NULL, NULL);
+ g_object_unref (reply);
+ goto out;
+ }
+
vtable->method_call (g_dbus_method_invocation_get_connection (invocation),
g_dbus_method_invocation_get_sender (invocation),
g_dbus_method_invocation_get_object_path (invocation),
g_object_ref (invocation),
g_dbus_method_invocation_get_user_data (invocation));
+ out:
return FALSE;
}
static gboolean
validate_and_maybe_schedule_method_call (GDBusConnection *connection,
GDBusMessage *message,
+ guint registration_id,
+ guint subtree_registration_id,
const GDBusInterfaceInfo *introspection_data,
const GDBusInterfaceVTable *vtable,
GMainContext *main_context,
parameters,
user_data);
g_variant_unref (parameters);
- g_object_set_data (G_OBJECT (invocation),
- "g-dbus-interface-vtable",
- (gpointer) vtable);
+
+ /* TODO: would be nicer with a real MethodData like we already
+ * have PropertyData and PropertyGetAllData... */
+ g_object_set_data (G_OBJECT (invocation), "g-dbus-interface-vtable", (gpointer) vtable);
+ g_object_set_data (G_OBJECT (invocation), "g-dbus-registration-id", GUINT_TO_POINTER (registration_id));
+ g_object_set_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id", GUINT_TO_POINTER (subtree_registration_id));
idle_source = g_idle_source_new ();
g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
handled = validate_and_maybe_schedule_method_call (connection,
message,
+ ei->id,
+ 0,
ei->introspection_data,
ei->vtable,
ei->context,
CONNECTION_LOCK (connection);
handled = validate_and_maybe_schedule_method_call (es->connection,
message,
+ 0,
+ es->id,
introspection_data,
interface_vtable,
es->context,
CONNECTION_LOCK (connection);
handled = validate_and_maybe_schedule_property_getset (es->connection,
message,
+ 0,
+ es->id,
is_property_get,
introspection_data,
interface_vtable,
CONNECTION_LOCK (connection);
handled = validate_and_maybe_schedule_property_get_all (es->connection,
message,
+ 0,
+ es->id,
introspection_data,
interface_vtable,
es->context,