summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-05-04 23:47:27 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-05-04 23:47:27 +0000
commit251f743f1501e99176c4071487b93567e94fefaa (patch)
treecc38fd6717aacb8d8f8f2f4ad32760d139260ea9 /common
parentcfb86c2cae67f27e673f19fd5e8447c1090679e4 (diff)
A more efficient strategy for introspection XML generation (only when it is requested and the object information has changed since the last generation)
Diffstat (limited to 'common')
-rw-r--r--common/dbus-helper.c188
1 files changed, 97 insertions, 91 deletions
diff --git a/common/dbus-helper.c b/common/dbus-helper.c
index 639b6d3f..40cd3eac 100644
--- a/common/dbus-helper.c
+++ b/common/dbus-helper.c
@@ -61,93 +61,6 @@ DBusHandlerResult dbus_connection_send_and_unref(DBusConnection *connection,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static DBusHandlerResult introspect(DBusConnection *connection,
- DBusMessage *message, struct generic_data *data)
-{
- DBusMessage *reply;
-
- if (dbus_message_has_signature(message,
- DBUS_TYPE_INVALID_AS_STRING) == FALSE) {
- error("Unexpected signature to introspect call");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- if (!data->introspect)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- reply = dbus_message_new_method_return(message);
- if (!reply)
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
- dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
- DBUS_TYPE_INVALID);
-
- return dbus_connection_send_and_unref(connection, reply);
-}
-
-static void generic_unregister(DBusConnection *connection, void *user_data)
-{
- struct generic_data *data = user_data;
-
- if (data->unregister_function)
- data->unregister_function(connection, data->user_data);
-
- g_free(data->introspect);
- g_free(data);
-}
-
-static struct interface_data *find_interface(GSList *interfaces,
- const char *name)
-{
- GSList *list;
-
- for (list = interfaces; list; list = list->next) {
- struct interface_data *iface = list->data;
- if (!strcmp(name, iface->name))
- return iface;
- }
-
- return NULL;
-}
-
-static DBusHandlerResult generic_message(DBusConnection *connection,
- DBusMessage *message, void *user_data)
-{
- struct generic_data *data = user_data;
- struct interface_data *iface;
- DBusMethodVTable *current;
- const char *interface;
-
- if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE,
- "Introspect") == TRUE)
- return introspect(connection, message, data);
-
- interface = dbus_message_get_interface(message);
-
- iface = find_interface(data->interfaces, interface);
- if (!iface)
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- for (current = iface->methods;
- current->name && current->message_function; current++) {
- if (dbus_message_is_method_call(message,
- iface->name, current->name) == FALSE)
- continue;
-
- if (dbus_message_has_signature(message,
- current->signature) == TRUE)
- return current->message_function(connection,
- message, data->user_data);
- }
-
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static DBusObjectPathVTable generic_table = {
- .unregister_function = generic_unregister,
- .message_function = generic_message,
-};
-
static void print_arguments(GString *gstr, const char *sig, const char *direction)
{
int i;
@@ -206,7 +119,9 @@ static void print_arguments(GString *gstr, const char *sig, const char *directio
}
}
-static void update_introspection_data(DBusConnection *conn, struct generic_data *data, const char *path)
+static void generate_introspection_xml(DBusConnection *conn,
+ struct generic_data *data,
+ const char *path)
{
GSList *list;
GString *gstr;
@@ -278,6 +193,94 @@ done:
data->introspect = g_string_free(gstr, FALSE);
}
+static DBusHandlerResult introspect(DBusConnection *connection,
+ DBusMessage *message, struct generic_data *data)
+{
+ DBusMessage *reply;
+
+ if (dbus_message_has_signature(message,
+ DBUS_TYPE_INVALID_AS_STRING) == FALSE) {
+ error("Unexpected signature to introspect call");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (!data->introspect)
+ generate_introspection_xml(connection, data,
+ dbus_message_get_path(message));
+
+ reply = dbus_message_new_method_return(message);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &data->introspect,
+ DBUS_TYPE_INVALID);
+
+ return dbus_connection_send_and_unref(connection, reply);
+}
+
+static void generic_unregister(DBusConnection *connection, void *user_data)
+{
+ struct generic_data *data = user_data;
+
+ if (data->unregister_function)
+ data->unregister_function(connection, data->user_data);
+
+ g_free(data->introspect);
+ g_free(data);
+}
+
+static struct interface_data *find_interface(GSList *interfaces,
+ const char *name)
+{
+ GSList *list;
+
+ for (list = interfaces; list; list = list->next) {
+ struct interface_data *iface = list->data;
+ if (!strcmp(name, iface->name))
+ return iface;
+ }
+
+ return NULL;
+}
+
+static DBusHandlerResult generic_message(DBusConnection *connection,
+ DBusMessage *message, void *user_data)
+{
+ struct generic_data *data = user_data;
+ struct interface_data *iface;
+ DBusMethodVTable *current;
+ const char *interface;
+
+ if (dbus_message_is_method_call(message, DBUS_INTERFACE_INTROSPECTABLE,
+ "Introspect") == TRUE)
+ return introspect(connection, message, data);
+
+ interface = dbus_message_get_interface(message);
+
+ iface = find_interface(data->interfaces, interface);
+ if (!iface)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ for (current = iface->methods;
+ current->name && current->message_function; current++) {
+ if (dbus_message_is_method_call(message,
+ iface->name, current->name) == FALSE)
+ continue;
+
+ if (dbus_message_has_signature(message,
+ current->signature) == TRUE)
+ return current->message_function(connection,
+ message, data->user_data);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusObjectPathVTable generic_table = {
+ .unregister_function = generic_unregister,
+ .message_function = generic_message,
+};
+
static void update_parent_data(DBusConnection *conn, const char *child_path)
{
struct generic_data *data;
@@ -299,7 +302,8 @@ static void update_parent_data(DBusConnection *conn, const char *child_path)
if (!data)
goto done;
- update_introspection_data(conn, data, parent_path);
+ g_free(data->introspect);
+ data->introspect = NULL;
done:
g_free(parent_path);
@@ -380,7 +384,8 @@ dbus_bool_t dbus_connection_register_interface(DBusConnection *connection,
data->interfaces = g_slist_append(data->interfaces, iface);
- update_introspection_data(connection, data, path);
+ g_free(data->introspect);
+ data->introspect = NULL;
return TRUE;
}
@@ -404,7 +409,8 @@ dbus_bool_t dbus_connection_unregister_interface(DBusConnection *connection,
g_free(iface->name);
g_free(iface);
- update_introspection_data(connection, data, path);
+ g_free(data->introspect);
+ data->introspect = NULL;
return TRUE;
}