GDBusInterface: add dup_object() method

This is needed for thread-safety ... yes, it would have been better to
make get_object() return a full reference and have something like a
peek_object() method return a borrowed reference for C convenience
(only a single vfunc would have been needed). But such an ABI break is
too late now...

Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
David Zeuthen 2012-01-26 14:16:28 -05:00
parent eb6c35f7c3
commit bc40fe582d
6 changed files with 75 additions and 1 deletions

View File

@ -3419,6 +3419,7 @@ GDBusInterface
GDBusInterfaceIface GDBusInterfaceIface
g_dbus_interface_get_info g_dbus_interface_get_info
g_dbus_interface_get_object g_dbus_interface_get_object
g_dbus_interface_dup_object
g_dbus_interface_set_object g_dbus_interface_set_object
<SUBSECTION Standard> <SUBSECTION Standard>
G_DBUS_INTERFACE G_DBUS_INTERFACE

View File

@ -66,11 +66,16 @@ g_dbus_interface_get_info (GDBusInterface *interface_)
} }
/** /**
* g_dbus_interface_get_object: * g_dbus_interface_get_object: (skip)
* @interface_: An exported D-Bus interface. * @interface_: An exported D-Bus interface.
* *
* Gets the #GDBusObject that @interface_ belongs to, if any. * Gets the #GDBusObject that @interface_ belongs to, if any.
* *
* <warning>It is not safe to use the returned object if @interface_
* or the returned object is being used from other threads. See
* g_dbus_interface_dup_object() for a thread-safe
* alternative.</warning>
*
* Returns: (transfer none): A #GDBusObject or %NULL. The returned * Returns: (transfer none): A #GDBusObject or %NULL. The returned
* reference belongs to @interface_ and should not be freed. * reference belongs to @interface_ and should not be freed.
* *
@ -83,6 +88,39 @@ g_dbus_interface_get_object (GDBusInterface *interface_)
return G_DBUS_INTERFACE_GET_IFACE (interface_)->get_object (interface_); return G_DBUS_INTERFACE_GET_IFACE (interface_)->get_object (interface_);
} }
/**
* g_dbus_interface_dup_object:
* @interface_: An exported D-Bus interface.
*
* Gets the #GDBusObject that @interface_ belongs to, if any.
*
* Returns: (transfer full): A #GDBusObject or %NULL. The returned
* reference should be freed with g_object_unref().
*
* Since: 2.32
*
* Rename to: g_dbus_interface_get_object
*/
GDBusObject *
g_dbus_interface_dup_object (GDBusInterface *interface_)
{
GDBusObject *ret;
g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface_), NULL);
if (G_LIKELY (G_DBUS_INTERFACE_GET_IFACE (interface_)->dup_object != NULL))
{
ret = G_DBUS_INTERFACE_GET_IFACE (interface_)->dup_object (interface_);
}
else
{
g_warning ("No dup_object() vfunc on type %s - using get_object() in a way that is not thread-safe.",
g_type_name_from_instance ((GTypeInstance *) interface_));
ret = G_DBUS_INTERFACE_GET_IFACE (interface_)->get_object (interface_);
if (ret != NULL)
g_object_ref (ret);
}
return ret;
}
/** /**
* g_dbus_interface_set_object: * g_dbus_interface_set_object:
* @interface_: An exported D-Bus interface. * @interface_: An exported D-Bus interface.

View File

@ -48,6 +48,7 @@ typedef struct _GDBusInterfaceIface GDBusInterfaceIface;
* @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_get_info(). * @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_get_info().
* @get_object: Gets the enclosing #GDBusObject. See g_dbus_interface_get_object(). * @get_object: Gets the enclosing #GDBusObject. See g_dbus_interface_get_object().
* @set_object: Sets the enclosing #GDBusObject. See g_dbus_interface_set_object(). * @set_object: Sets the enclosing #GDBusObject. See g_dbus_interface_set_object().
* @dup_object: Gets a reference to the enclosing #GDBusObject. See g_dbus_interface_dup_object(). Added in 2.32.
* *
* Base type for D-Bus interfaces. * Base type for D-Bus interfaces.
* *
@ -62,6 +63,7 @@ struct _GDBusInterfaceIface
GDBusObject *(*get_object) (GDBusInterface *interface_); GDBusObject *(*get_object) (GDBusInterface *interface_);
void (*set_object) (GDBusInterface *interface_, void (*set_object) (GDBusInterface *interface_,
GDBusObject *object); GDBusObject *object);
GDBusObject *(*dup_object) (GDBusInterface *interface_);
}; };
GType g_dbus_interface_get_type (void) G_GNUC_CONST; GType g_dbus_interface_get_type (void) G_GNUC_CONST;
@ -69,6 +71,7 @@ GDBusInterfaceInfo *g_dbus_interface_get_info (GDBusInterface *in
GDBusObject *g_dbus_interface_get_object (GDBusInterface *interface_); GDBusObject *g_dbus_interface_get_object (GDBusInterface *interface_);
void g_dbus_interface_set_object (GDBusInterface *interface_, void g_dbus_interface_set_object (GDBusInterface *interface_,
GDBusObject *object); GDBusObject *object);
GDBusObject *g_dbus_interface_dup_object (GDBusInterface *interface_);
G_END_DECLS G_END_DECLS

View File

@ -415,6 +415,19 @@ g_dbus_interface_skeleton_get_object (GDBusInterface *interface_)
return ret; return ret;
} }
static GDBusObject *
g_dbus_interface_skeleton_dup_object (GDBusInterface *interface_)
{
GDBusInterfaceSkeleton *interface = G_DBUS_INTERFACE_SKELETON (interface_);
GDBusObject *ret;
g_mutex_lock (&interface->priv->lock);
ret = interface->priv->object;
if (ret != NULL)
g_object_ref (ret);
g_mutex_unlock (&interface->priv->lock);
return ret;
}
static void static void
g_dbus_interface_skeleton_set_object (GDBusInterface *interface_, g_dbus_interface_skeleton_set_object (GDBusInterface *interface_,
GDBusObject *object) GDBusObject *object)
@ -434,6 +447,7 @@ dbus_interface_interface_init (GDBusInterfaceIface *iface)
{ {
iface->get_info = _g_dbus_interface_skeleton_get_info; iface->get_info = _g_dbus_interface_skeleton_get_info;
iface->get_object = g_dbus_interface_skeleton_get_object; iface->get_object = g_dbus_interface_skeleton_get_object;
iface->dup_object = g_dbus_interface_skeleton_dup_object;
iface->set_object = g_dbus_interface_skeleton_set_object; iface->set_object = g_dbus_interface_skeleton_set_object;
} }

View File

@ -153,6 +153,7 @@ struct _GDBusProxyPrivate
gboolean initialized; gboolean initialized;
/* mutable, protected by properties_lock */
GDBusObject *object; GDBusObject *object;
SignalSubscriptionData *signal_subscription_data; SignalSubscriptionData *signal_subscription_data;
@ -3080,16 +3081,31 @@ _g_dbus_proxy_get_object (GDBusInterface *interface)
return proxy->priv->object; return proxy->priv->object;
} }
static GDBusObject *
_g_dbus_proxy_dup_object (GDBusInterface *interface)
{
GDBusProxy *proxy = G_DBUS_PROXY (interface);
GDBusObject *ret = NULL;
G_LOCK (properties_lock);
if (proxy->priv->object != NULL)
ret = g_object_ref (proxy->priv->object);
G_UNLOCK (properties_lock);
return ret;
}
static void static void
_g_dbus_proxy_set_object (GDBusInterface *interface, _g_dbus_proxy_set_object (GDBusInterface *interface,
GDBusObject *object) GDBusObject *object)
{ {
GDBusProxy *proxy = G_DBUS_PROXY (interface); GDBusProxy *proxy = G_DBUS_PROXY (interface);
G_LOCK (properties_lock);
if (proxy->priv->object != NULL) if (proxy->priv->object != NULL)
g_object_remove_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object); g_object_remove_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object);
proxy->priv->object = object; proxy->priv->object = object;
if (proxy->priv->object != NULL) if (proxy->priv->object != NULL)
g_object_add_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object); g_object_add_weak_pointer (G_OBJECT (proxy->priv->object), (gpointer *) &proxy->priv->object);
G_UNLOCK (properties_lock);
} }
static void static void
@ -3097,6 +3113,7 @@ dbus_interface_iface_init (GDBusInterfaceIface *dbus_interface_iface)
{ {
dbus_interface_iface->get_info = _g_dbus_proxy_get_info; dbus_interface_iface->get_info = _g_dbus_proxy_get_info;
dbus_interface_iface->get_object = _g_dbus_proxy_get_object; dbus_interface_iface->get_object = _g_dbus_proxy_get_object;
dbus_interface_iface->dup_object = _g_dbus_proxy_dup_object;
dbus_interface_iface->set_object = _g_dbus_proxy_set_object; dbus_interface_iface->set_object = _g_dbus_proxy_set_object;
} }

View File

@ -1569,6 +1569,7 @@ g_tls_password_get_flags
g_tls_password_get_description g_tls_password_get_description
g_dbus_interface_get_info g_dbus_interface_get_info
g_dbus_interface_get_object g_dbus_interface_get_object
g_dbus_interface_dup_object
g_dbus_interface_get_type g_dbus_interface_get_type
g_dbus_interface_set_object g_dbus_interface_set_object
g_dbus_interface_skeleton_export g_dbus_interface_skeleton_export