aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2026-10-23 16:38:04 +0200
committerMarvin W <git@larma.de>2026-10-23 17:01:44 +0200
commit2eb311938665f92ef48e2cfa030720fc68ca7cc9 (patch)
tree64ee8aa646873e5c3af62fc29f767c456fe88b7a
parent9e9f46d820257900a47410ba87c3aac601d0a71e (diff)
xmpp-vala: Fix deadlocks with cancellables
-rw-r--r--xmpp-vala/src/module/iq/module.vala31
-rw-r--r--xmpp-vala/src/module/xep/0047_in_band_bytestreams.vala4
2 files changed, 26 insertions, 9 deletions
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;