diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-06-17 12:06:11 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2011-08-15 10:44:28 +0100 |
commit | 1b38cecf7bbdb8a99ef13616b8c661dfb0bc060f (patch) | |
tree | ae8750f8db74d1b86840595eb31181bad208b1bf | |
parent | af31c9c21efeec8a38c73de24d82a2038d80f74e (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.c | 16 |
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); |