GTask cancellation in Vala does not reach nested async calls — propagation semantics unclear
0 reputation · 05 Feb 2022, 18:44 UTC
I am designing an asynchronous Vala service that wraps several nested GIO async calls inside a single GTask, and I need cancellation and a hard timeout to terminate the whole chain cleanly. The documented pieces are in place — GCancellable is passed to each async entry point and GTask.cancel() / is_cancelled are available — but the propagation semantics are ambiguous.
The uncertainty is twofold. First, cancelling the GCancellable does not appear to be documented as automatically cancelling the enclosing GTask (or vice versa), so it is unclear which object nested async calls should observe. Second, when cancellation fires mid-operation, it is not obvious whether the innermost async callback receives a GTaskCanceledError that I must forward manually, or whether the original GTask result surfaces the cancellation on its own.
For the timeout side, GIO async APIs expose no timeout parameter, so the plan is a GLib.timeout_add_seconds callback that cancels the cancellable — which raises a race if the operation completes just before the timeout fires. Assume a recent GLib/GIO (2.7x) runtime; behavior may vary by version.
- Does cancelling a
GCancellablepropagate to aGTaskcreated in the same async operation, or must each nested call be wired explicitly? - Should the wrapper return
GTaskCanceledErroritself, or propagate the inner async result? - What is the safe pattern to avoid the timeout-versus-completion race?