Hang in Tuba.Network.get_parser_from_inputstream ()
Describe the bug
I'm sitting in a coffee shop, with a spotty network connection. Tuba seems to hang, and GNOME Shell offers me to kill it as unresponsive.
Here's a backtrace:
#0 0x00007ff5702406c2 in __syscall_cancel_arch () at /lib64/libc.so.6
#1 0x00007ff5702349da in __internal_syscall_cancel () at /lib64/libc.so.6
#2 0x00007ff570234a24 in __syscall_cancel () at /lib64/libc.so.6
#3 0x00007ff5702adc4e in poll () at /lib64/libc.so.6
#4 0x00007ff57204f46b in poll
(__fds=, __nfds=, __timeout=)
at /usr/include/bits/poll2.h:44
#5 0x00007ff571cdd5af in g_socket_condition_timed_wait
(socket=, condition=, timeout_us=, cancellable=0x0, error=0x55ab9899c2d8) at ../gio/gsocket.c:4738
#6 0x00007ff571cdd92a in g_socket_receive_with_timeout
(socket=0x55ab989063a0, buffer=0x55ab98a86b13, size=541, timeout_us=-1, cancellable=0x0, error=0x55ab9899c2d8) at ../gio/gsocket.c:3382
#7 0x00007ff571cbb296 in g_input_stream_read
(stream=0x55ab988e7960, buffer=0x55ab98a86b13, count=541, cancellable=0x0, error=0x55ab9899c2d8) at ../gio/ginputstream.c:200
--Type for more, q to quit, c to continue without paging--
#8 0x00007ff53439d281 in g_tls_connection_gnutls_pull_func ()
at /usr/lib64/gio/modules/libgiognutls.so
#9 0x00007ff56fc1304a in _gnutls_io_read_buffered () at /lib64/libgnutls.so.30
#10 0x00007ff56fc07cfc in _gnutls_recv_in_buffers () at /lib64/libgnutls.so.30
#11 0x00007ff56fc0a320 in _gnutls_recv_int () at /lib64/libgnutls.so.30
#12 0x00007ff5343a26df in g_tls_connection_gnutls_read ()
at /usr/lib64/gio/modules/libgiognutls.so
#13 0x00007ff5343a502b in g_tls_connection_base_read ()
at /usr/lib64/gio/modules/libgiognutls.so
#14 0x00007ff5343a55ec in g_tls_input_stream_read ()
at /usr/lib64/gio/modules/libgiognutls.so
#15 0x00007ff571cbb296 in g_input_stream_read
(stream=0x55ab97f38d70, buffer=0x55ab98936950, count=128, cancellable=0x0, error=0x7ffce171d3a0) at ../gio/ginputstream.c:200
#16 0x00007ff571e7dab4 in soup_filter_input_stream_read_fn ()
at /lib64/libsoup-3.0.so.0
#17 0x00007ff571cbb296 in g_input_stream_read
(stream=0x55ab9768c560, buffer=0x55ab98936950, count=128, cancellable=0x0, error=0x7ffce171d3a0) at ../gio/ginputstream.c:200
#18 0x00007ff571e80ba1 in soup_filter_input_stream_read_until ()
at /lib64/libsoup-3.0.so.0
#19 0x00007ff571e5cbc0 in read_internal () at /lib64/libsoup-3.0.so.0
#20 0x00007ff571cbb296 in g_input_stream_read
--Type for more, q to quit, c to continue without paging--
(stream=0x55ab97fe0d90, buffer=0x55ab98a91750, count=8192, cancellable=0x0, error=0x7ffce171d810) at ../gio/ginputstream.c:200
#21 0x00007ff571c8afcb in fill_input_buffer
(stream=stream@entry=0x55ab98a8c260, at_least_size=at_least_size@entry=8192, blocking=blocking@entry=1, cancellable=cancellable@entry=0x0, error=error@entry=0x7ffce171d810) at ../gio/gconverterinputstream.c:363
#22 0x00007ff571c8b4a4 in read_internal
(stream=0x55ab98a8c260, buffer=0x55ab98ad3b39, count=8192, blocking=1, cancellable=0x0, error=0x7ffce171d810) at ../gio/gconverterinputstream.c:426
#23 0x00007ff571cbb296 in g_input_stream_read
(stream=0x55ab98a8c260, buffer=0x55ab98ad3b39, count=8192, cancellable=0x0, error=0x7ffce171d810) at ../gio/ginputstream.c:200
#24 0x00007ff571e7dab4 in soup_filter_input_stream_read_fn ()
at /lib64/libsoup-3.0.so.0
#25 0x00007ff571e74257 in soup_client_input_stream_read_fn ()
at /lib64/libsoup-3.0.so.0
#26 0x00007ff571cbb296 in g_input_stream_read
(stream=0x55ab95c24bc0, buffer=0x55ab98ad3b39, count=8192, cancellable=0x0, error=0x7ffce171d810) at ../gio/ginputstream.c:200
#27 0x00007ff571c59aad in json_parser_load_from_stream ()
at /lib64/libjson-glib-1.0.so.0
#28 0x000055ab790e93ec in tuba_network_get_parser_from_inputstream ()
#29 0x000055ab79125cfc in ___lambda139__tuba_network_success_callback ()
--Type for more, q to quit, c to continue without paging--
#30 0x000055ab790e9aa9 in ___lambda11__gasync_ready_callback ()
#31 0x00007ff571ce9e7c in g_task_return_now (task=0x55ab98798780)
at ../gio/gtask.c:1363
#32 0x00007ff571cef590 in g_task_return
(type=, task=0x55ab98798780) at ../gio/gtask.c:1432
#33 g_task_return (task=0x55ab98798780, type=)
at ../gio/gtask.c:1389
#34 0x00007ff571e92e72 in async_send_request_return_result ()
at /lib64/libsoup-3.0.so.0
#35 0x00007ff571e95ced in run_until_read_done.lto_priv ()
at /lib64/libsoup-3.0.so.0
#36 0x00007ff571ce9e7c in g_task_return_now (task=0x55ab970c53a0)
at ../gio/gtask.c:1363
#37 0x00007ff571cef590 in g_task_return
(type=, task=0x55ab970c53a0) at ../gio/gtask.c:1432
#38 g_task_return (task=0x55ab970c53a0, type=)
at ../gio/gtask.c:1389
#39 0x00007ff571e651c5 in io_run_until_read_async () at /lib64/libsoup-3.0.so.0
#40 0x00007ff571e65208 in io_run_until_read_ready () at /lib64/libsoup-3.0.so.0
#41 0x00007ff57203b880 in g_main_dispatch (context=0x55ab94f7f780)
at ../glib/gmain.c:3398
#42 g_main_context_dispatch_unlocked (context=0x55ab94f7f780)
at ../glib/gmain.c:4249
--Type for more, q to quit, c to continue without paging--
#43 0x00007ff5720447c8 in g_main_context_iterate_unlocked
(context=context@entry=0x55ab94f7f780, block=block@entry=1, dispatch=dispatch@entry=1, self=) at ../glib/gmain.c:4314
#44 0x00007ff572044973 in g_main_context_iteration
(context=context@entry=0x55ab94f7f780, may_block=may_block@entry=1)
at ../glib/gmain.c:4379
#45 0x00007ff571d2202d in g_application_run
(application=0x55ab951c5a50, argc=, argv=)
at ../gio/gapplication.c:2715
#46 0x000055ab7904797e in main ()
As you can see, it's blocking on a synchronous network read on the main thread 😱. Specifically, Tuba.Network.get_parser_from_inputstream () calls Json.Parser.load_from_stream (), which reads the stream in a blocking manner.
Steps To Reproduce
- Have a spotty network connection.
- Try
(gdb) start (gdb) b soup_client_input_stream_read_fn thread 1 - Consider using something like https://gitlab.gnome.org/chergert/iobt to catch issues like this
Logs and/or Screenshots
No response
Instance Backend
Mastodon
Operating System
Fedora Linux 42
Package
OS repositories
Troubleshooting information
No response
Additional Context
No response
:/ this is from when I was doing the migration to libsoup 3 and still learning Vala, soup and json-glib, I wonder if using the async one will have a positive impact on performance too in the whole app!
That function is used a lot for every API related request, mostly in callbacks, I'll see if I can quickly convert them to async, otherwise I'll do it the long way and wrap them in begin/end
is #1481 good enough? I can't really reproduce it (even though my connection is terrible)
#1481 replaced load_from_stream with load_from_stream_async