mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-05-05 05:26:52 +02:00
GDBusObjectManagerServer: Add locking
Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
4e7ef619eb
commit
027b63ab96
@ -75,8 +75,12 @@ static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectMan
|
|||||||
RegistrationData *data,
|
RegistrationData *data,
|
||||||
const gchar *const *interfaces);
|
const gchar *const *interfaces);
|
||||||
|
|
||||||
|
static gboolean g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
|
||||||
|
const gchar *object_path);
|
||||||
|
|
||||||
struct _GDBusObjectManagerServerPrivate
|
struct _GDBusObjectManagerServerPrivate
|
||||||
{
|
{
|
||||||
|
GMutex *lock;
|
||||||
GDBusConnection *connection;
|
GDBusConnection *connection;
|
||||||
gchar *object_path;
|
gchar *object_path;
|
||||||
gchar *object_path_ending_in_slash;
|
gchar *object_path_ending_in_slash;
|
||||||
@ -112,6 +116,8 @@ g_dbus_object_manager_server_finalize (GObject *object)
|
|||||||
g_free (manager->priv->object_path);
|
g_free (manager->priv->object_path);
|
||||||
g_free (manager->priv->object_path_ending_in_slash);
|
g_free (manager->priv->object_path_ending_in_slash);
|
||||||
|
|
||||||
|
g_mutex_free (manager->priv->lock);
|
||||||
|
|
||||||
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
|
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
|
||||||
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
|
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -127,7 +133,9 @@ g_dbus_object_manager_server_get_property (GObject *object,
|
|||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_CONNECTION:
|
case PROP_CONNECTION:
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
g_value_set_object (value, manager->priv->connection);
|
g_value_set_object (value, manager->priv->connection);
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PROP_OBJECT_PATH:
|
case PROP_OBJECT_PATH:
|
||||||
@ -221,6 +229,7 @@ g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
|
|||||||
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
|
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
|
||||||
G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
|
G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
|
||||||
GDBusObjectManagerServerPrivate);
|
GDBusObjectManagerServerPrivate);
|
||||||
|
manager->priv->lock = g_mutex_new ();
|
||||||
manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
|
manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
|
||||||
g_str_equal,
|
g_str_equal,
|
||||||
g_free,
|
g_free,
|
||||||
@ -267,8 +276,13 @@ g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
|
|||||||
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
|
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
|
||||||
g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));
|
g_return_if_fail (connection == NULL || G_IS_DBUS_CONNECTION (connection));
|
||||||
|
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
|
||||||
if (manager->priv->connection == connection)
|
if (manager->priv->connection == connection)
|
||||||
goto out;
|
{
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (manager->priv->connection != NULL)
|
if (manager->priv->connection != NULL)
|
||||||
{
|
{
|
||||||
@ -281,6 +295,8 @@ g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
|
|||||||
if (manager->priv->connection != NULL)
|
if (manager->priv->connection != NULL)
|
||||||
export_all (manager);
|
export_all (manager);
|
||||||
|
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (manager), "connection");
|
g_object_notify (G_OBJECT (manager), "connection");
|
||||||
out:
|
out:
|
||||||
;
|
;
|
||||||
@ -301,8 +317,12 @@ g_dbus_object_manager_server_set_connection (GDBusObjectManagerServer *manager,
|
|||||||
GDBusConnection *
|
GDBusConnection *
|
||||||
g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
|
g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
|
||||||
{
|
{
|
||||||
|
GDBusConnection *ret;
|
||||||
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
|
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
|
||||||
return manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
ret = manager->priv->connection != NULL ? g_object_ref (manager->priv->connection) : NULL;
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@ -386,7 +406,9 @@ on_interface_added (GDBusObject *object,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
RegistrationData *data = user_data;
|
RegistrationData *data = user_data;
|
||||||
|
g_mutex_lock (data->manager->priv->lock);
|
||||||
registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
|
registration_data_export_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
|
||||||
|
g_mutex_unlock (data->manager->priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -395,7 +417,9 @@ on_interface_removed (GDBusObject *object,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
RegistrationData *data = user_data;
|
RegistrationData *data = user_data;
|
||||||
|
g_mutex_lock (data->manager->priv->lock);
|
||||||
registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
|
registration_data_unexport_interface (data, G_DBUS_INTERFACE_SKELETON (interface));
|
||||||
|
g_mutex_unlock (data->manager->priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
@ -425,35 +449,15 @@ registration_data_free (RegistrationData *data)
|
|||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* g_dbus_object_manager_server_export:
|
g_dbus_object_manager_server_export_unlocked (GDBusObjectManagerServer *manager,
|
||||||
* @manager: A #GDBusObjectManagerServer.
|
GDBusObjectSkeleton *object,
|
||||||
* @object: A #GDBusObjectSkeleton.
|
const gchar *object_path)
|
||||||
*
|
|
||||||
* Exports @object on @manager.
|
|
||||||
*
|
|
||||||
* If there is already a #GDBusObject exported at the object path,
|
|
||||||
* then the old object is removed.
|
|
||||||
*
|
|
||||||
* The object path for @object must be in the hierarchy rooted by the
|
|
||||||
* object path for @manager.
|
|
||||||
*
|
|
||||||
* Note that @manager will take a reference on @object for as long as
|
|
||||||
* it is exported.
|
|
||||||
*
|
|
||||||
* Since: 2.30
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
|
|
||||||
GDBusObjectSkeleton *object)
|
|
||||||
{
|
{
|
||||||
RegistrationData *data;
|
RegistrationData *data;
|
||||||
GList *existing_interfaces;
|
GList *existing_interfaces;
|
||||||
GList *l;
|
GList *l;
|
||||||
GPtrArray *interface_names;
|
GPtrArray *interface_names;
|
||||||
const gchar *object_path;
|
|
||||||
|
|
||||||
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
|
|
||||||
|
|
||||||
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
|
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
|
||||||
g_return_if_fail (G_IS_DBUS_OBJECT (object));
|
g_return_if_fail (G_IS_DBUS_OBJECT (object));
|
||||||
@ -463,7 +467,7 @@ g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
|
|||||||
|
|
||||||
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
|
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
g_dbus_object_manager_server_unexport (manager, object_path);
|
g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
|
||||||
|
|
||||||
data = g_new0 (RegistrationData, 1);
|
data = g_new0 (RegistrationData, 1);
|
||||||
data->object = g_object_ref (object);
|
data->object = g_object_ref (object);
|
||||||
@ -507,6 +511,35 @@ g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
|
|||||||
data);
|
data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_object_manager_server_export:
|
||||||
|
* @manager: A #GDBusObjectManagerServer.
|
||||||
|
* @object: A #GDBusObjectSkeleton.
|
||||||
|
*
|
||||||
|
* Exports @object on @manager.
|
||||||
|
*
|
||||||
|
* If there is already a #GDBusObject exported at the object path,
|
||||||
|
* then the old object is removed.
|
||||||
|
*
|
||||||
|
* The object path for @object must be in the hierarchy rooted by the
|
||||||
|
* object path for @manager.
|
||||||
|
*
|
||||||
|
* Note that @manager will take a reference on @object for as long as
|
||||||
|
* it is exported.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
|
||||||
|
GDBusObjectSkeleton *object)
|
||||||
|
{
|
||||||
|
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
g_dbus_object_manager_server_export_unlocked (manager, object,
|
||||||
|
g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_dbus_object_manager_server_export_uniquely:
|
* g_dbus_object_manager_server_export_uniquely:
|
||||||
* @manager: A #GDBusObjectManagerServer.
|
* @manager: A #GDBusObjectManagerServer.
|
||||||
@ -535,6 +568,8 @@ g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
|
|||||||
g_return_if_fail (G_IS_DBUS_OBJECT (object));
|
g_return_if_fail (G_IS_DBUS_OBJECT (object));
|
||||||
g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
|
g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
|
||||||
|
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
|
||||||
object_path = g_strdup (orig_object_path);
|
object_path = g_strdup (orig_object_path);
|
||||||
count = 1;
|
count = 1;
|
||||||
modified = FALSE;
|
modified = FALSE;
|
||||||
@ -551,33 +586,23 @@ g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager,
|
|||||||
modified = TRUE;
|
modified = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_dbus_object_manager_server_export_unlocked (manager, object, object_path);
|
||||||
|
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
|
||||||
if (modified)
|
if (modified)
|
||||||
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
|
g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path);
|
||||||
|
|
||||||
g_dbus_object_manager_server_export (manager, object);
|
|
||||||
|
|
||||||
g_free (object_path);
|
g_free (object_path);
|
||||||
g_free (orig_object_path);
|
g_free (orig_object_path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
* g_dbus_object_manager_server_unexport:
|
|
||||||
* @manager: A #GDBusObjectManagerServer.
|
static gboolean
|
||||||
* @object_path: An object path.
|
g_dbus_object_manager_server_unexport_unlocked (GDBusObjectManagerServer *manager,
|
||||||
*
|
const gchar *object_path)
|
||||||
* If @manager has an object at @path, removes the object. Otherwise
|
|
||||||
* does nothing.
|
|
||||||
*
|
|
||||||
* Note that @object_path must be in the hierarchy rooted by the
|
|
||||||
* object path for @manager.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
|
|
||||||
*
|
|
||||||
* Since: 2.30
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
|
|
||||||
const gchar *object_path)
|
|
||||||
{
|
{
|
||||||
RegistrationData *data;
|
RegistrationData *data;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
@ -611,6 +636,33 @@ g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_dbus_object_manager_server_unexport:
|
||||||
|
* @manager: A #GDBusObjectManagerServer.
|
||||||
|
* @object_path: An object path.
|
||||||
|
*
|
||||||
|
* If @manager has an object at @path, removes the object. Otherwise
|
||||||
|
* does nothing.
|
||||||
|
*
|
||||||
|
* Note that @object_path must be in the hierarchy rooted by the
|
||||||
|
* object path for @manager.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if object at @object_path was removed, %FALSE otherwise.
|
||||||
|
*
|
||||||
|
* Since: 2.30
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
|
||||||
|
const gchar *object_path)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), FALSE);
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
ret = g_dbus_object_manager_server_unexport_unlocked (manager, object_path);
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -745,6 +797,8 @@ manager_method_call (GDBusConnection *connection,
|
|||||||
GHashTableIter object_iter;
|
GHashTableIter object_iter;
|
||||||
RegistrationData *data;
|
RegistrationData *data;
|
||||||
|
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
|
||||||
if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
|
if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
|
||||||
{
|
{
|
||||||
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
|
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
|
||||||
@ -785,6 +839,7 @@ manager_method_call (GDBusConnection *connection,
|
|||||||
"Unknown method %s - only GetManagedObjects() is supported",
|
"Unknown method %s - only GetManagedObjects() is supported",
|
||||||
method_name);
|
method_name);
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GDBusInterfaceVTable manager_interface_vtable =
|
static const GDBusInterfaceVTable manager_interface_vtable =
|
||||||
@ -893,6 +948,8 @@ g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager)
|
|||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
RegistrationData *data;
|
RegistrationData *data;
|
||||||
|
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
|
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
|
g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
|
||||||
@ -900,6 +957,8 @@ g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager)
|
|||||||
ret = g_list_prepend (ret, g_object_ref (data->object));
|
ret = g_list_prepend (ret, g_object_ref (data->object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,9 +978,13 @@ g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager,
|
|||||||
RegistrationData *data;
|
RegistrationData *data;
|
||||||
|
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
|
|
||||||
|
g_mutex_lock (manager->priv->lock);
|
||||||
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
|
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
|
||||||
if (data != NULL)
|
if (data != NULL)
|
||||||
ret = g_object_ref (data->object);
|
ret = g_object_ref (data->object);
|
||||||
|
g_mutex_unlock (manager->priv->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user