diff options
author | Eduardo Lima (Etrunko) <etrunko@redhat.com> | 2017-02-02 15:13:48 -0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2017-02-06 16:58:56 +0100 |
commit | 65b5fce90f34f7b52801f09daa28696e53468bae (patch) | |
tree | 1b3333f8b38c1989df272ddb4046dba7d0d2bec0 | |
parent | 25beefa304af1fa5ce529401ccb19aac252dd185 (diff) |
proxy: Check if operation is cancelled before disconnecting signal
According to the documentation, g_cancellable_disconnect() waits for the
signal handler to finish, and if it is called from the handler itself, it
will result in a deadlock. To avoid it, we check if the operation is
cancelled and if so, call g_signal_handler_disconnect() instead of
g_cancellable_disconnect().
https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-disconnect
Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
-rw-r--r-- | govirt/ovirt-proxy.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c index 70c08ac..73c4d4a 100644 --- a/govirt/ovirt-proxy.c +++ b/govirt/ovirt-proxy.c @@ -216,7 +216,15 @@ static void ovirt_proxy_call_async_data_free(OvirtProxyCallAsyncData *data) g_object_unref(G_OBJECT(data->result)); } if ((data->cancellable != NULL) && (data->cancellable_cb_id != 0)) { - g_cancellable_disconnect(data->cancellable, data->cancellable_cb_id); + if (g_cancellable_is_cancelled(data->cancellable)) { + /* Cancellable has already been cancelled, we don't need to use + * g_cancellable_disconnect() to disconnect the signal handler + * as we know the 'cancelled' signal is no longer going to be emitted + */ + g_signal_handler_disconnect(data->cancellable, data->cancellable_cb_id); + } else { + g_cancellable_disconnect(data->cancellable, data->cancellable_cb_id); + } } g_clear_object(&data->cancellable); g_slice_free(OvirtProxyCallAsyncData, data); |