[Pkg-telepathy-commits] [telepathy-glib-1] 09/212: TpProxy: have a GDBusConnection and GDBusProxies instead of dbus-glib
Simon McVittie
smcv at debian.org
Wed May 14 12:08:45 UTC 2014
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian
in repository telepathy-glib-1.
commit 8910d6bdd114f21dc3670934dffc490b83bd12e4
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Thu Mar 13 15:00:22 2014 +0000
TpProxy: have a GDBusConnection and GDBusProxies instead of dbus-glib
---
telepathy-glib/core-proxy.c | 4 +-
telepathy-glib/dbus-daemon.c | 2 +-
telepathy-glib/dbus-daemon.h | 2 +-
telepathy-glib/proxy-internal.h | 2 +-
telepathy-glib/proxy-subclass.h | 3 +-
telepathy-glib/proxy.c | 199 ++++++++++++++++------------
telepathy-glib/proxy.h | 2 +-
tests/dbus/dbus.c | 6 +-
tests/dbus/get-interface-after-invalidate.c | 2 +-
9 files changed, 127 insertions(+), 95 deletions(-)
diff --git a/telepathy-glib/core-proxy.c b/telepathy-glib/core-proxy.c
index db38cd8..c841022 100644
--- a/telepathy-glib/core-proxy.c
+++ b/telepathy-glib/core-proxy.c
@@ -31,8 +31,8 @@
static TpProxyImplementation _tp_proxy_implementation = { NULL };
-DBusGProxy *
-tp_proxy_get_interface_by_id (TpProxy *proxy,
+GDBusProxy *
+tp_proxy_get_interface_by_id (gpointer proxy,
GQuark iface,
GError **error)
{
diff --git a/telepathy-glib/dbus-daemon.c b/telepathy-glib/dbus-daemon.c
index 8a54f79..676d60f 100644
--- a/telepathy-glib/dbus-daemon.c
+++ b/telepathy-glib/dbus-daemon.c
@@ -135,7 +135,7 @@ tp_dbus_daemon_dup (GError **error)
* Since: 0.7.1
*/
TpDBusDaemon *
-tp_dbus_daemon_new (DBusGConnection *connection)
+tp_dbus_daemon_new (GDBusConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
diff --git a/telepathy-glib/dbus-daemon.h b/telepathy-glib/dbus-daemon.h
index 6171b4a..ed5c719 100644
--- a/telepathy-glib/dbus-daemon.h
+++ b/telepathy-glib/dbus-daemon.h
@@ -54,7 +54,7 @@ GType tp_dbus_daemon_get_type (void);
TpDBusDaemon *tp_dbus_daemon_dup (GError **error) G_GNUC_WARN_UNUSED_RESULT;
-TpDBusDaemon *tp_dbus_daemon_new (DBusGConnection *connection)
+TpDBusDaemon *tp_dbus_daemon_new (GDBusConnection *connection)
G_GNUC_WARN_UNUSED_RESULT;
typedef void (*TpDBusDaemonNameOwnerChangedCb) (TpDBusDaemon *bus_daemon,
diff --git a/telepathy-glib/proxy-internal.h b/telepathy-glib/proxy-internal.h
index c70ca82..2007f53 100644
--- a/telepathy-glib/proxy-internal.h
+++ b/telepathy-glib/proxy-internal.h
@@ -28,7 +28,7 @@ typedef struct {
const gchar *version;
gsize size;
- DBusGProxy *(*get_interface_by_id) (TpProxy *,
+ GDBusProxy *(*get_interface_by_id) (TpProxy *,
GQuark,
GError **);
diff --git a/telepathy-glib/proxy-subclass.h b/telepathy-glib/proxy-subclass.h
index 1e3f0d1..7f2c5b4 100644
--- a/telepathy-glib/proxy-subclass.h
+++ b/telepathy-glib/proxy-subclass.h
@@ -57,8 +57,7 @@ TpProxySignalConnection *tp_proxy_signal_connection_v0_new (TpProxy *self,
void tp_proxy_signal_connection_v0_take_results
(TpProxySignalConnection *sc, GValueArray *args);
-_TP_AVAILABLE_IN_0_20
-DBusGProxy *tp_proxy_get_interface_by_id (TpProxy *self, GQuark iface,
+GDBusProxy *tp_proxy_get_interface_by_id (TpProxy *self, GQuark iface,
GError **error);
void tp_proxy_add_interface_by_id (TpProxy *self, GQuark iface);
diff --git a/telepathy-glib/proxy.c b/telepathy-glib/proxy.c
index 954732e..65823eb 100644
--- a/telepathy-glib/proxy.c
+++ b/telepathy-glib/proxy.c
@@ -151,7 +151,7 @@ tp_dbus_errors_quark (void)
* @see_also: #TpProxy
*
* The implementations of #TpProxy subclasses and "mixin" functions need
- * access to the underlying dbus-glib objects used to implement the
+ * access to the underlying GDBus objects used to implement the
* #TpProxy API.
*
* Mixin functions to implement particular D-Bus interfaces should usually
@@ -339,15 +339,15 @@ tp_proxy_prepare_request_finish (TpProxyPrepareRequest *req,
struct _TpProxyPrivate {
TpDBusDaemon *dbus_daemon;
- DBusGConnection *dbus_connection;
+ GDBusConnection *dbus_connection;
gchar *bus_name;
gchar *object_path;
GError *invalidated;
- /* GQuark for interface => either a ref'd DBusGProxy *,
+ /* GQuark for interface => either a ref'd GDBusProxy *,
* or the TpProxy itself used as a dummy value to indicate that
- * the DBusGProxy has not been needed yet */
+ * the GDBusProxy has not been needed yet */
GData *interfaces;
/* feature => FeatureState */
@@ -365,6 +365,9 @@ struct _TpProxyPrivate {
guint pending_will_announce_calls;
TpClientFactory *factory;
+
+ gulong gdbus_closed_signal;
+ guint unique_name_watch;
};
G_DEFINE_TYPE (TpProxy, tp_proxy, G_TYPE_OBJECT)
@@ -387,8 +390,6 @@ enum {
static guint signals[N_SIGNALS] = {0};
-static void tp_proxy_iface_destroyed_cb (DBusGProxy *dgproxy, TpProxy *self);
-
/**
* tp_proxy_get_interface_by_id: (skip)
* @self: the TpProxy
@@ -399,7 +400,7 @@ static void tp_proxy_iface_destroyed_cb (DBusGProxy *dgproxy, TpProxy *self);
*
* <!-- -->
*
- * Returns: a borrowed reference to a #DBusGProxy
+ * Returns: a borrowed reference to a #GDBusProxy
* for which the bus name and object path are the same as for @self, but the
* interface is as given (or %NULL if an @error is raised).
* The reference is only valid as long as @self is.
@@ -409,41 +410,39 @@ static void tp_proxy_iface_destroyed_cb (DBusGProxy *dgproxy, TpProxy *self);
/* that's implemented in the core library, but it calls this: */
-DBusGProxy *
+GDBusProxy *
_tp_proxy_get_interface_by_id (TpProxy *self,
GQuark iface,
GError **error)
{
- gpointer dgproxy;
+ gpointer iface_proxy;
g_return_val_if_fail (TP_IS_PROXY (self), NULL);
if (!_tp_proxy_check_interface_by_id (self, iface, error))
return NULL;
- dgproxy = g_datalist_id_get_data (&self->priv->interfaces, iface);
+ iface_proxy = g_datalist_id_get_data (&self->priv->interfaces, iface);
- if (dgproxy == self)
+ if (iface_proxy == self)
{
/* dummy value - we've never actually needed the interface, so we
* didn't create it, to avoid binding to all the signals */
- dgproxy = dbus_g_proxy_new_for_name (self->priv->dbus_connection,
- self->priv->bus_name, self->priv->object_path, g_quark_to_string (iface));
- DEBUG ("%p: %s DBusGProxy is %p", self, g_quark_to_string (iface),
- dgproxy);
-
- g_signal_connect (dgproxy, "destroy",
- G_CALLBACK (tp_proxy_iface_destroyed_cb), self);
+ iface_proxy = g_dbus_proxy_new_sync (self->priv->dbus_connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL, /* FIXME: add interface info */
+ self->priv->bus_name,
+ self->priv->object_path,
+ g_quark_to_string (iface),
+ NULL, /* cancellable */
+ error);
g_datalist_id_set_data_full (&self->priv->interfaces, iface,
- dgproxy, g_object_unref);
-
- g_signal_emit (self, signals[SIGNAL_INTERFACE_ADDED], 0,
- (guint) iface, dgproxy);
+ iface_proxy, g_object_unref);
}
- return dgproxy;
+ return iface_proxy;
}
/**
@@ -549,24 +548,6 @@ tp_proxy_has_interface (gpointer self,
g_datalist_id_get_data (&proxy->priv->interfaces, q) != NULL);
}
-static void
-tp_proxy_lose_interface (GQuark unused,
- gpointer dgproxy_or_self,
- gpointer self)
-{
- if (dgproxy_or_self != self)
- g_signal_handlers_disconnect_by_func (dgproxy_or_self,
- G_CALLBACK (tp_proxy_iface_destroyed_cb), self);
-}
-
-static void
-tp_proxy_lose_interfaces (TpProxy *self)
-{
- g_datalist_foreach (&self->priv->interfaces,
- tp_proxy_lose_interface, self);
-
- g_datalist_clear (&self->priv->interfaces);
-}
static void tp_proxy_poll_features (TpProxy *self, const GError *error);
@@ -587,13 +568,8 @@ tp_proxy_emit_invalidated (gpointer p)
/* Don't clear the datalist until after we've emitted the signal, so
* the pending call and signal connection friend classes can still get
* to the proxies */
- tp_proxy_lose_interfaces (self);
-
- if (self->priv->dbus_connection != NULL)
- {
- dbus_g_connection_unref (self->priv->dbus_connection);
- self->priv->dbus_connection = NULL;
- }
+ g_datalist_clear (&self->priv->interfaces);
+ g_clear_object (&self->priv->dbus_connection);
return FALSE;
}
@@ -615,39 +591,69 @@ tp_proxy_invalidate (TpProxy *self, const GError *error)
g_return_if_fail (self != NULL);
g_return_if_fail (error != NULL);
- if (self->priv->invalidated == NULL)
+ if (self->priv->invalidated != NULL)
+ {
+ DEBUG ("%p: already invalidated", self);
+ return;
+ }
+
+ DEBUG ("%p: %s #%d: %s", self, g_quark_to_string (error->domain),
+ error->code, error->message);
+ self->priv->invalidated = g_error_copy (error);
+
+ if (self->priv->unique_name_watch != 0)
{
- DEBUG ("%p: %s", self, error->message);
- self->priv->invalidated = g_error_copy (error);
+ /* there's no point in watching for this now */
+ g_bus_unwatch_name (self->priv->unique_name_watch);
+ self->priv->unique_name_watch = 0;
+ }
- tp_proxy_emit_invalidated (self);
+ if (self->priv->gdbus_closed_signal != 0)
+ {
+ /* there's no point in watching for this now */
+ g_signal_handler_disconnect (self->priv->dbus_connection,
+ self->priv->gdbus_closed_signal);
+ self->priv->gdbus_closed_signal = 0;
}
+
+ tp_proxy_emit_invalidated (self);
}
static void
-tp_proxy_iface_destroyed_cb (DBusGProxy *dgproxy,
- TpProxy *self)
+tp_proxy_closed_cb (GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ gpointer user_data)
{
- /* We can't call any API on the proxy now. Because the proxies are all
- * for the same bus name, we can assume that all of them are equally
- * useless now */
- tp_proxy_lose_interfaces (self);
-
- /* We need to be able to delay emitting the invalidated signal, so that
- * any queued-up method calls and signal handlers will run first, and so
- * it doesn't try to reenter libdbus.
- */
- if (self->priv->invalidated == NULL)
+ TpProxy *self = TP_PROXY (user_data);
+
+ if (error != NULL)
{
- DEBUG ("%p", self);
- self->priv->invalidated = g_error_new_literal (TP_DBUS_ERRORS,
- TP_DBUS_ERROR_NAME_OWNER_LOST, "Name owner lost (service crashed?)");
+ tp_proxy_invalidate (self, error);
+ }
+ else
+ {
+ GError e = { TP_DBUS_ERRORS, TP_DBUS_ERROR_NAME_OWNER_LOST,
+ "Disconnected from D-Bus by local request" };
- g_idle_add_full (G_PRIORITY_HIGH, tp_proxy_emit_invalidated,
- g_object_ref (self), g_object_unref);
+ tp_proxy_invalidate (self, &e);
}
}
+static void
+tp_proxy_unique_name_vanished_cb (GDBusConnection *conn,
+ const gchar *name,
+ gpointer user_data)
+{
+ TpProxy *self = TP_PROXY (user_data);
+ GError e = { TP_DBUS_ERRORS, TP_DBUS_ERROR_NAME_OWNER_LOST,
+ "Name owner lost (service crashed?)" };
+
+ DEBUG ("%p: %s", self, name);
+
+ tp_proxy_invalidate (self, &e);
+}
+
/**
* tp_proxy_add_interface_by_id: (skip)
* @self: the TpProxy, which must not have become #TpProxy::invalidated.
@@ -656,7 +662,7 @@ tp_proxy_iface_destroyed_cb (DBusGProxy *dgproxy,
* Declare that this proxy supports a given interface.
*
* To use methods and signals of that interface, either call
- * tp_proxy_get_interface_by_id() to get the #DBusGProxy, or use the
+ * tp_proxy_get_interface_by_id() to get the #GDBusProxy, or use the
* tp_cli_* wrapper functions (strongly recommended).
*
* If the interface is the proxy's "main interface", or has already been
@@ -668,7 +674,7 @@ void
tp_proxy_add_interface_by_id (TpProxy *self,
GQuark iface)
{
- DBusGProxy *iface_proxy = g_datalist_id_get_data (&self->priv->interfaces,
+ GDBusProxy *iface_proxy = g_datalist_id_get_data (&self->priv->interfaces,
iface);
g_return_if_fail
@@ -679,8 +685,8 @@ tp_proxy_add_interface_by_id (TpProxy *self,
if (iface_proxy == NULL)
{
- /* we don't want to actually create it just yet - dbus-glib will
- * helpfully wake us up on every signal, if we do. So we set a
+ /* we don't want to actually create it just yet - we'll get
+ * woken up on every signal, if we do. So we set a
* dummy value (self), and replace it with the real value in
* tp_proxy_get_interface_by_id */
g_datalist_id_set_data_full (&self->priv->interfaces, iface,
@@ -863,7 +869,7 @@ tp_proxy_get_property (GObject *object,
}
break;
case PROP_DBUS_CONNECTION:
- g_value_set_boxed (value, self->priv->dbus_connection);
+ g_value_set_object (value, self->priv->dbus_connection);
break;
case PROP_BUS_NAME:
g_value_set_string (value, self->priv->bus_name);
@@ -914,7 +920,7 @@ tp_proxy_set_property (GObject *object,
{
if (self->priv->dbus_connection == NULL)
{
- self->priv->dbus_connection = dbus_g_connection_ref (
+ self->priv->dbus_connection = g_object_ref (
tp_proxy_get_dbus_connection (self->priv->dbus_daemon));
}
else
@@ -927,17 +933,17 @@ tp_proxy_set_property (GObject *object,
break;
case PROP_DBUS_CONNECTION:
{
- DBusGConnection *conn = g_value_get_boxed (value);
+ GDBusConnection *conn = g_value_get_object (value);
/* if we're given a NULL dbus-connection, but we've got a
- * DBusGConnection from the dbus-daemon, we want to keep it */
+ * GDBusConnection from the dbus-daemon, we want to keep it */
if (conn == NULL)
return;
if (self->priv->dbus_connection == NULL)
- self->priv->dbus_connection = g_value_dup_boxed (value);
+ self->priv->dbus_connection = g_value_dup_object (value);
- g_assert (self->priv->dbus_connection == g_value_get_boxed (value));
+ g_assert (self->priv->dbus_connection == g_value_get_object (value));
}
break;
case PROP_BUS_NAME:
@@ -1065,6 +1071,9 @@ tp_proxy_constructor (GType type,
g_return_val_if_fail (self->priv->object_path != NULL, NULL);
g_return_val_if_fail (self->priv->bus_name != NULL, NULL);
+ DEBUG ("%s:%s -> %s %p", self->priv->bus_name, self->priv->object_path,
+ G_OBJECT_TYPE_NAME (self), self);
+
g_return_val_if_fail (tp_dbus_check_valid_object_path (self->priv->object_path,
NULL), NULL);
g_return_val_if_fail (tp_dbus_check_valid_bus_name (self->priv->bus_name,
@@ -1086,6 +1095,27 @@ tp_proxy_constructor (GType type,
g_return_val_if_fail (self->priv->bus_name[0] == ':', NULL);
}
+ self->priv->gdbus_closed_signal = g_signal_connect_object (
+ self->priv->dbus_connection, "closed",
+ G_CALLBACK (tp_proxy_closed_cb), self, 0);
+
+ if (self->priv->bus_name[0] == ':')
+ {
+ /* We're tracking a unique name. When it becomes unowned,
+ * signal the destruction of the TpProxy. */
+ DEBUG ("%p: watching whether unique name %s disappears",
+ self, self->priv->bus_name);
+
+ self->priv->unique_name_watch = g_bus_watch_name_on_connection (
+ self->priv->dbus_connection,
+ self->priv->bus_name,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ NULL,
+ tp_proxy_unique_name_vanished_cb,
+ self,
+ NULL);
+ }
+
return (GObject *) self;
}
@@ -1100,6 +1130,9 @@ tp_proxy_dispose (GObject *object)
DEBUG ("%p", self);
+ /* One day we should stop doing this. When that day comes, we need
+ * to make sure the cleanup from tp_proxy_invalidate() is duplicated
+ * here, and is idempotent. */
tp_proxy_invalidate (self, &e);
tp_clear_object (&self->priv->dbus_daemon);
@@ -1229,8 +1262,8 @@ tp_proxy_class_init (TpProxyClass *klass)
* The D-Bus connection for this object. Read-only except during
* construction.
*/
- param_spec = g_param_spec_boxed ("dbus-connection", "D-Bus connection",
- "The D-Bus connection used by this object", DBUS_TYPE_G_CONNECTION,
+ param_spec = g_param_spec_object ("dbus-connection", "D-Bus connection",
+ "The D-Bus connection used by this object", G_TYPE_DBUS_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DBUS_CONNECTION,
param_spec);
@@ -1378,11 +1411,11 @@ tp_proxy_get_dbus_daemon (gpointer self)
*
* Returns: a borrowed reference to the D-Bus connection used by this object.
* The caller must reference the returned pointer with
- * dbus_g_connection_ref() if it will be kept.
+ * g_object_ref() if it will be kept.
*
* Since: 0.7.17
*/
-DBusGConnection *
+GDBusConnection *
tp_proxy_get_dbus_connection (gpointer self)
{
TpProxy *proxy = TP_PROXY (self);
diff --git a/telepathy-glib/proxy.h b/telepathy-glib/proxy.h
index 085de34..3b4c68f 100644
--- a/telepathy-glib/proxy.h
+++ b/telepathy-glib/proxy.h
@@ -160,7 +160,7 @@ TpClientFactory *tp_proxy_get_factory (gpointer self);
TpDBusDaemon *tp_proxy_get_dbus_daemon (gpointer self);
-DBusGConnection *tp_proxy_get_dbus_connection (gpointer self);
+GDBusConnection *tp_proxy_get_dbus_connection (gpointer self);
const gchar *tp_proxy_get_bus_name (gpointer self);
diff --git a/tests/dbus/dbus.c b/tests/dbus/dbus.c
index 925b9f6..2cd7b21 100644
--- a/tests/dbus/dbus.c
+++ b/tests/dbus/dbus.c
@@ -111,7 +111,7 @@ test_properties (void)
TpDBusDaemon *bus = tp_dbus_daemon_dup (NULL);
gchar *bus_name;
gchar *object_path;
- DBusGConnection *dbus_conn;
+ GDBusConnection *dbus_conn;
g_object_get (bus,
"dbus-connection", &dbus_conn,
@@ -124,11 +124,11 @@ test_properties (void)
object_path);
g_assert_cmpstr (bus_name, ==, "org.freedesktop.DBus");
- g_assert (dbus_conn != NULL);
+ g_assert (G_IS_DBUS_CONNECTION (dbus_conn));
g_free (bus_name);
g_free (object_path);
- dbus_g_connection_unref (dbus_conn);
+ g_object_unref (dbus_conn);
g_object_unref (bus);
}
diff --git a/tests/dbus/get-interface-after-invalidate.c b/tests/dbus/get-interface-after-invalidate.c
index 675507d..0fb2162 100644
--- a/tests/dbus/get-interface-after-invalidate.c
+++ b/tests/dbus/get-interface-after-invalidate.c
@@ -11,7 +11,7 @@ static void
test_get_interface_after_invalidate (void)
{
TpDBusDaemon *bus_daemon;
- DBusGProxy *props;
+ GDBusProxy *props;
GError invalidation_reason = { TP_ERROR, TP_ERROR_NOT_YOURS, "bees!" };
GError *error = NULL;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/telepathy-glib-1.git
More information about the Pkg-telepathy-commits
mailing list