| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com> |
| Date: Thu, 2 Feb 2017 15:13:48 -0200 |
| Subject: [PATCH] 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> |
| |
| govirt/ovirt-proxy.c | 10 +++++++++- |
| 1 file changed, 9 insertions(+), 1 deletion(-) |
| |
| diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c |
| index 2b690b6..921e22e 100644 |
| |
| |
| @@ -218,7 +218,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); |