libsoup resets the GCancellable passed to soup_session_send
I've been debugging an issue affecting shutdown of the GStreamer DASH client (dashdemux) where some threads fail to terminate in a timely manner. The DASH client uses libsoup though another GStreamer element, souphttpsrc, which implements cancellation of ongoing download requests with a GCancellable (https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/blob/master/ext/soup/gstsouphttpsrc.h#L92), which is passed to the libsoup APIs and is also used to cancel the element's own threads.
What I have been seeing is that sometimes termination of an ongoing download request takes much longer than expected, which causes timeouts in other parts of the system. I have tracked this down to what I would consider a bug in libsoup, in that APIs such as soup_session_send() take a GCancellable* which the client can use to cancel an ongoing request, but libsoup sometimes resets (i.e. calls g_cancellable_reset()) the client-supplied cancellable.
In the souphttpsrc case the client code is expecting that it can cancel the cancellable to cancel the ongoing libsoup operations, and that the cancellable will stay in the cancelled state so that other threads in the client code can check its value and terminate. But in practice this does not work reliably because sometimes libsoup resets the cancellable before the other client threads see the cancelled status. This means that these threads don't terminate in a timely fashion.
It seems to me a flaw in the API design if the libsoup code changes the state of the cancellable which is really intended as a way for the client code to control libsoup, not as a feedback mechanism. Or, it should be documented that the caller should not rely on the value of the cancellable once it has been cancelled.
I've tracked down the code in question to this location in soup-session.c where the cancellable is copied into the SoupMessageQueueItem https://gitlab.gnome.org/GNOME/libsoup/blob/master/libsoup/soup-session.c#L4422
And this is where it gets reset: https://gitlab.gnome.org/GNOME/libsoup/blob/master/libsoup/soup-message-queue.c#L61
Commenting out the reset call fixes my issue but I assume the reset was originally added for a good reason.
Any advice on whether this is a bug in libsoup or incorrect API usage on the part of the GStreamer folks would be very much appreciated
Best regards
Tom