From 2eb311938665f92ef48e2cfa030720fc68ca7cc9 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Fri, 23 Oct 2026 16:38:04 +0200 Subject: xmpp-vala: Fix deadlocks with cancellables --- xmpp-vala/src/module/iq/module.vala | 31 +++++++++++++++++----- .../src/module/xep/0047_in_band_bytestreams.vala | 4 +-- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'xmpp-vala/src/module') diff --git a/xmpp-vala/src/module/iq/module.vala b/xmpp-vala/src/module/iq/module.vala index 917f6660..c87db897 100644 --- a/xmpp-vala/src/module/iq/module.vala +++ b/xmpp-vala/src/module/iq/module.vala @@ -17,22 +17,39 @@ namespace Xmpp.Iq { preprocess_outgoing_iq_set_get(stream, iq); Iq.Stanza? return_stanza = null; + IOError? return_error = null; + bool yielded = false; responseListeners[iq.id] = new ResponseListener((_, result_iq) => { return_stanza = result_iq; - if (cancellable == null || !cancellable.is_cancelled()) { - Idle.add(send_iq_async.callback); + if (yielded) send_iq_async.callback(); + }); + stream.write_async.begin(iq.stanza, io_priority, cancellable, (_, res) => { + try { + stream.write_async.end(res); + } catch (IOError e) { + return_error = e; } }); - yield stream.write_async(iq.stanza, io_priority, cancellable); ulong cancelled_handler_id = 0; if (cancellable != null) { - cancelled_handler_id = cancellable.cancelled.connect(() => Idle.add(send_iq_async.callback)); + cancelled_handler_id = cancellable.connect(() => { + if (yielded) send_iq_async.callback(); + }); + } + if ((cancellable == null || !cancellable.is_cancelled()) && return_error == null) { + yielded = true; + yield; + yielded = false; } - yield; if (cancellable != null) { - cancellable.disconnect(cancelled_handler_id); - cancellable.set_error_if_cancelled(); + if (cancellable.is_cancelled()) { + cancellable.set_error_if_cancelled(); + } else { + cancellable.disconnect(cancelled_handler_id); + } } + responseListeners.unset(iq.id); + if (return_error != null) throw return_error; return return_stanza; } diff --git a/xmpp-vala/src/module/xep/0047_in_band_bytestreams.vala b/xmpp-vala/src/module/xep/0047_in_band_bytestreams.vala index 1e423b49..74034a8a 100644 --- a/xmpp-vala/src/module/xep/0047_in_band_bytestreams.vala +++ b/xmpp-vala/src/module/xep/0047_in_band_bytestreams.vala @@ -177,7 +177,7 @@ public class Connection : IOStream { if (read_callback != null) { Idle.add((owned) read_callback, read_callback_priority); read_callback = null; - if (read_callback_cancellable != null) { + if (read_callback_cancellable != null && !read_callback_cancellable.is_cancelled()) { read_callback_cancellable.disconnect(read_callback_cancellable_id); } read_callback_cancellable = null; @@ -187,7 +187,7 @@ public class Connection : IOStream { if (write_callback != null) { Idle.add((owned) write_callback, write_callback_priority); write_callback = null; - if (write_callback_cancellable != null) { + if (write_callback_cancellable != null && !write_callback_cancellable.is_cancelled()) { write_callback_cancellable.disconnect(write_callback_cancellable_id); } write_callback_cancellable = null; -- cgit v1.3