[glib] GDBusObjectManagerClient: Add locking
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] GDBusObjectManagerClient: Add locking
- Date: Mon, 29 Aug 2011 20:20:58 +0000 (UTC)
commit 4e7ef619ebe025bd97d2a3ef8dd8c1b7baa903b2
Author: David Zeuthen <davidz redhat com>
Date: Mon Aug 29 16:20:50 2011 -0400
GDBusObjectManagerClient: Add locking
Signed-off-by: David Zeuthen <davidz redhat com>
gio/gdbusobjectmanagerclient.c | 107 +++++++++++++++++++++++++++++++++-------
1 files changed, 88 insertions(+), 19 deletions(-)
---
diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c
index 9e8368d..2f581db 100644
--- a/gio/gdbusobjectmanagerclient.c
+++ b/gio/gdbusobjectmanagerclient.c
@@ -125,6 +125,8 @@
struct _GDBusObjectManagerClientPrivate
{
+ GMutex *lock;
+
GBusType bus_type;
GDBusConnection *connection;
gchar *object_path;
@@ -212,15 +214,17 @@ g_dbus_object_manager_client_finalize (GObject *object)
if (manager->priv->get_proxy_type_destroy_notify != NULL)
manager->priv->get_proxy_type_destroy_notify (manager->priv->get_proxy_type_user_data);
+ g_mutex_free (manager->priv->lock);
+
if (G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize (object);
}
static void
g_dbus_object_manager_client_get_property (GObject *_object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
@@ -254,9 +258,9 @@ g_dbus_object_manager_client_get_property (GObject *_object,
static void
g_dbus_object_manager_client_set_property (GObject *_object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
@@ -568,6 +572,7 @@ g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager)
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
GDBusObjectManagerClientPrivate);
+ manager->priv->lock = g_mutex_new ();
manager->priv->map_object_path_to_object_proxy = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
@@ -707,7 +712,7 @@ g_dbus_object_manager_client_new (GDBusConnection *connection,
*/
GDBusObjectManager *
g_dbus_object_manager_client_new_finish (GAsyncResult *res,
- GError **error)
+ GError **error)
{
GObject *object;
GObject *source_object;
@@ -894,8 +899,12 @@ g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res,
GDBusConnection *
g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager)
{
+ GDBusConnection *ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
- return manager->priv->connection;
+ g_mutex_lock (manager->priv->lock);
+ ret = manager->priv->connection;
+ g_mutex_unlock (manager->priv->lock);
+ return ret;
}
/**
@@ -912,8 +921,12 @@ g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager)
const gchar *
g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager)
{
+ const gchar *ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
- return manager->priv->name;
+ g_mutex_lock (manager->priv->lock);
+ ret = manager->priv->name;
+ g_mutex_unlock (manager->priv->lock);
+ return ret;
}
/**
@@ -930,8 +943,12 @@ g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager)
GDBusObjectManagerClientFlags
g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager)
{
+ GDBusObjectManagerClientFlags ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
- return manager->priv->flags;
+ g_mutex_lock (manager->priv->lock);
+ ret = manager->priv->flags;
+ g_mutex_unlock (manager->priv->lock);
+ return ret;
}
/**
@@ -951,8 +968,12 @@ g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager)
gchar *
g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager)
{
+ gchar *ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
- return g_strdup (manager->priv->name_owner);
+ g_mutex_lock (manager->priv->lock);
+ ret = g_strdup (manager->priv->name_owner);
+ g_mutex_unlock (manager->priv->lock);
+ return ret;
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -973,9 +994,15 @@ signal_cb (GDBusConnection *connection,
GDBusObjectProxy *object_proxy;
GDBusInterface *interface;
+ g_mutex_lock (manager->priv->lock);
object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
if (object_proxy == NULL)
- goto out;
+ {
+ g_mutex_unlock (manager->priv->lock);
+ goto out;
+ }
+ g_object_ref (object_proxy);
+ g_mutex_unlock (manager->priv->lock);
//g_debug ("yay, signal_cb %s %s: %s\n", signal_name, object_path, g_variant_print (parameters, TRUE));
@@ -1062,7 +1089,8 @@ signal_cb (GDBusConnection *connection,
}
out:
- ;
+ if (object_proxy != NULL)
+ g_object_ref (object_proxy);
}
static void
@@ -1196,6 +1224,7 @@ on_notify_g_name_owner (GObject *object,
gchar *old_name_owner;
gchar *new_name_owner;
+ g_mutex_lock (manager->priv->lock);
old_name_owner = manager->priv->name_owner;
new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
manager->priv->name_owner = NULL;
@@ -1205,16 +1234,19 @@ on_notify_g_name_owner (GObject *object,
GList *l;
GList *proxies;
+ /* remote manager changed; nuke all local proxies */
+ proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
+ g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
+ g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);
+
+ g_mutex_unlock (manager->priv->lock);
+
/* do the :name-owner notify with a NULL name - this way the user knows
* the ::object-proxy-removed following is because the name owner went
* away
*/
g_object_notify (G_OBJECT (manager), "name-owner");
- /* remote manager changed; nuke all local proxies */
- proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
- g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
- g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);
for (l = proxies; l != NULL; l = l->next)
{
GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data);
@@ -1226,6 +1258,10 @@ on_notify_g_name_owner (GObject *object,
/* nuke local filter */
maybe_unsubscribe_signals (manager);
}
+ else
+ {
+ g_mutex_unlock (manager->priv->lock);
+ }
if (new_name_owner != NULL)
{
@@ -1263,7 +1299,9 @@ on_notify_g_name_owner (GObject *object,
/* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
* way the user knows that the signals were emitted because the name owner came back
*/
+ g_mutex_lock (manager->priv->lock);
manager->priv->name_owner = new_name_owner;
+ g_mutex_unlock (manager->priv->lock);
g_object_notify (G_OBJECT (manager), "name-owner");
}
@@ -1379,10 +1417,16 @@ add_interfaces (GDBusObjectManagerClient *manager,
GVariantIter iter;
const gchar *interface_name;
GVariant *properties;
+ GList *interface_added_signals, *l;
+ GDBusProxy *interface_proxy;
g_return_if_fail (g_dbus_is_unique_name (name_owner));
+ g_mutex_lock (manager->priv->lock);
+
+ interface_added_signals = NULL;
added = FALSE;
+
op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
if (op == NULL)
{
@@ -1405,6 +1449,7 @@ add_interfaces (GDBusObjectManagerClient *manager,
NULL);
added = TRUE;
}
+ g_object_ref (op);
g_variant_iter_init (&iter, ifaces_and_properties);
while (g_variant_iter_next (&iter,
@@ -1412,7 +1457,6 @@ add_interfaces (GDBusObjectManagerClient *manager,
&interface_name,
&properties))
{
- GDBusProxy *interface_proxy;
GError *error;
GType interface_proxy_type;
@@ -1476,12 +1520,23 @@ add_interfaces (GDBusObjectManagerClient *manager,
_g_dbus_object_proxy_add_interface (op, interface_proxy);
if (!added)
- g_signal_emit_by_name (manager, "interface-added", op, interface_proxy);
+ interface_added_signals = g_list_append (interface_added_signals, g_object_ref (interface_proxy));
g_object_unref (interface_proxy);
}
g_variant_unref (properties);
}
+ g_mutex_unlock (manager->priv->lock);
+
+ /* now that we don't hold the lock any more, emit signals */
+ for (l = interface_added_signals; l != NULL; l = l->next)
+ {
+ interface_proxy = G_DBUS_PROXY (l->data);
+ g_signal_emit_by_name (manager, "interface-added", op, interface_proxy);
+ g_object_unref (interface_proxy);
+ }
+ g_list_free (interface_added_signals);
+
if (added)
{
g_hash_table_insert (manager->priv->map_object_path_to_object_proxy,
@@ -1489,6 +1544,8 @@ add_interfaces (GDBusObjectManagerClient *manager,
op);
g_signal_emit_by_name (manager, "object-added", op);
}
+ g_object_unref (op);
+
}
static void
@@ -1502,12 +1559,15 @@ remove_interfaces (GDBusObjectManagerClient *manager,
guint num_interfaces;
guint num_interfaces_to_remove;
+ g_mutex_lock (manager->priv->lock);
+
op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
if (op == NULL)
{
g_warning ("%s: Processing InterfaceRemoved signal for path %s but no object proxy exists",
G_STRLOC,
object_path);
+ g_mutex_unlock (manager->priv->lock);
goto out;
}
@@ -1523,11 +1583,14 @@ remove_interfaces (GDBusObjectManagerClient *manager,
{
g_object_ref (op);
g_warn_if_fail (g_hash_table_remove (manager->priv->map_object_path_to_object_proxy, object_path));
+ g_mutex_unlock (manager->priv->lock);
g_signal_emit_by_name (manager, "object-removed", op);
g_object_unref (op);
}
else
{
+ g_object_ref (op);
+ g_mutex_unlock (manager->priv->lock);
for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++)
{
GDBusInterface *interface;
@@ -1539,6 +1602,7 @@ remove_interfaces (GDBusObjectManagerClient *manager,
g_object_unref (interface);
}
}
+ g_object_unref (op);
}
out:
;
@@ -1619,9 +1683,11 @@ g_dbus_object_manager_client_get_object (GDBusObjectManager *_manager,
GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
GDBusObject *ret;
+ g_mutex_lock (manager->priv->lock);
ret = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
if (ret != NULL)
g_object_ref (ret);
+ g_mutex_unlock (manager->priv->lock);
return ret;
}
@@ -1654,8 +1720,11 @@ g_dbus_object_manager_client_get_objects (GDBusObjectManager *_manager)
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
+ g_mutex_lock (manager->priv->lock);
ret = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
g_list_foreach (ret, (GFunc) g_object_ref, NULL);
+ g_mutex_unlock (manager->priv->lock);
+
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]