summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2011-06-17 12:06:11 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-08-15 10:44:28 +0100
commit1b38cecf7bbdb8a99ef13616b8c661dfb0bc060f (patch)
treeae8750f8db74d1b86840595eb31181bad208b1bf
parentaf31c9c21efeec8a38c73de24d82a2038d80f74e (diff)
DBusGProxy: cope gracefully with call_id == 0
As well as happening on a programming error or OOM (which both provoke critical warnings), dbus_g_proxy_begin_call_internal() can legitimately fail if we got disconnected from D-Bus (so can't send any more), but are still working through our backlog of incoming messages (so we haven't got round to the Disconnected message yet, so the DBusGProxy hasn't emitted ::destroy). fd.o #12675 fixed dbus_g_proxy_call(), but dbus_g_proxy_call_with_timeout() and the asynchronous API still need similar treatment. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=38406 Reviewed-by: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk>
-rw-r--r--dbus/dbus-gproxy.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/dbus/dbus-gproxy.c b/dbus/dbus-gproxy.c
index 83fe8b9..ea0c311 100644
--- a/dbus/dbus-gproxy.c
+++ b/dbus/dbus-gproxy.c
@@ -2332,6 +2332,16 @@ dbus_g_proxy_end_call_internal (DBusGProxy *proxy,
DBusPendingCall *pending;
DBusGProxyPrivate *priv = DBUS_G_PROXY_GET_PRIVATE(proxy);
+ if (call_id == 0)
+ {
+ /* Being disconnected is the only reason this can happen, except
+ * for programmer error; if it was programmer error, we already
+ * emitted a critical warning. */
+ g_set_error (error, DBUS_GERROR, DBUS_GERROR_DISCONNECTED,
+ "Disconnected from D-Bus (or argument error during call)");
+ return FALSE;
+ }
+
reply = NULL;
ret = FALSE;
n_retvals_processed = 0;
@@ -2836,6 +2846,12 @@ dbus_g_proxy_cancel_call (DBusGProxy *proxy,
call_id = DBUS_G_PROXY_CALL_TO_ID (call);
+ if (call_id == 0)
+ {
+ /* nothing to cancel */
+ return;
+ }
+
pending = g_hash_table_lookup (priv->pending_calls, GUINT_TO_POINTER (call_id));
g_hash_table_remove (priv->pending_calls, GUINT_TO_POINTER (call_id));
g_return_if_fail (pending != NULL);