Cancellation might not be asynchronous under certain circumstances
I made these changes to
gnome-online-accounts to simplify the code by exploiting the fact that cancellation of messages with the non-deprecated
SoupSession is meant to be asynchronous:
The soup_session_abort and soup_session_cancel_message documentation says that the response callback for the cancelled messages will be called in the next iteration of the main loop after the cancelling API has returned.
In the case of
soup_session_abortis called in response to
GCancellable::cancelleddue to the user cancelling the enveloping asynchronous operation
- the response callback frees the task data of the asynchronous operation which leads to g_cancellable_disconnect.
soup_session_abort doesn't invoke the response callback asynchronously, then the code will deadlock because one cannot disconnect from a
GCancellable from its
GCancellable::cancelled handler, and the above
gnome-online-accounts changes would not work.
While testing those changes, I found a way to trigger a deadlock. The backtrace looked like this:
Sadly, now that I installed all the debug symbols, I have lost my magic powers to win the necessary races to trigger the deadlock. I believe it could be because of some local DNS cache, so hopefully I will be successful in the near future.
Here is some documentation on how to play with