From ac79141ef561c9d87494350c2b28b0d37975650a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 07:47:26 +0000 Subject: Use reference counting for the object paths --- gdbus/object.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 13 deletions(-) (limited to 'gdbus') diff --git a/gdbus/object.c b/gdbus/object.c index bc3ea5e7..762ab74e 100644 --- a/gdbus/object.c +++ b/gdbus/object.c @@ -42,6 +42,7 @@ struct generic_data { DBusObjectPathUnregisterFunction unregister_function; GSList *interfaces; char *introspect; + unsigned int refcount; }; struct interface_data { @@ -318,37 +319,75 @@ done: g_free(parent_path); } -dbus_bool_t dbus_connection_create_object_path(DBusConnection *connection, - const char *path, void *user_data, - DBusObjectPathUnregisterFunction function) +static struct generic_data *object_path_ref(DBusConnection *connection, + const char *path) { - struct generic_data *data; + struct generic_data *data = NULL; - data = g_new0(struct generic_data, 1); + if (dbus_connection_get_object_path_data(connection, path, + (void *) &data) || !data) { + data->refcount++; + return data; + } - data->user_data = user_data; - data->unregister_function = function; + data = g_new0(struct generic_data, 1); data->introspect = g_strdup(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE ""); + data->refcount = 1; + if (!dbus_connection_register_object_path(connection, path, &generic_table, data)) { g_free(data->introspect); g_free(data); - return FALSE; + return NULL; } invalidate_parent_data(connection, path); + return data; +} + +static void object_path_unref(DBusConnection *connection, const char *path) +{ + struct generic_data *data = NULL; + + if (!dbus_connection_get_object_path_data(connection, path, + (void *) &data) || !data) + return; + + data->refcount--; + + if (data->refcount > 0) + return; + + invalidate_parent_data(connection, path); + + dbus_connection_unregister_object_path(connection, path); +} + +dbus_bool_t dbus_connection_create_object_path(DBusConnection *connection, + const char *path, void *user_data, + DBusObjectPathUnregisterFunction function) +{ + struct generic_data *data; + + data = object_path_ref(connection, path); + if (data == NULL) + return FALSE; + + data->user_data = user_data; + data->unregister_function = function; + return TRUE; } dbus_bool_t dbus_connection_destroy_object_path(DBusConnection *connection, const char *path) { - invalidate_parent_data(connection, path); + object_path_unref(connection, path); - return dbus_connection_unregister_object_path(connection, path); + return TRUE; } dbus_bool_t dbus_connection_get_object_user_data(DBusConnection *connection, @@ -673,11 +712,11 @@ gboolean g_dbus_register_interface(DBusConnection *connection, void *user_data, GDBusDestroyFunction destroy) { - struct generic_data *data = NULL; + struct generic_data *data; struct interface_data *iface; - if (!dbus_connection_get_object_path_data(connection, path, - (void *) &data) || !data) + data = object_path_ref(connection, path); + if (data == NULL) return FALSE; if (find_interface(data->interfaces, name)) @@ -725,5 +764,7 @@ gboolean g_dbus_unregister_interface(DBusConnection *connection, g_free(data->introspect); data->introspect = NULL; + object_path_unref(connection, path); + return TRUE; } -- cgit