On Fri, Jan 12, 2024 at 03:07:04 +0000, Michael Gold wrote:
> I sometimes notice this if I navigate into a large directory, and resize
> the window while the "spinner" is animating at the top-right corner.  It
> can be difficult to reproduce once Linux has the data cached.

It looks like the spinner--rotate_dash()--is actually the culprit.  That
calls mc_refresh(), which empties sigwinch_pipe before do_nc() makes its
first dlg_run() call:
        (gdb) bt
        #0  tty_flush_winch () at ./lib/tty/tty.c:224
        #1  0x00005555556567fb in dialog_change_screen_size () at 
./lib/widget/dialog-switch.c:426
        #2  0x0000555555656781 in mc_refresh () at 
./lib/widget/dialog-switch.c:411
        #3  0x000055555558f98e in rotate_dash (show=1) at 
./src/filemanager/layout.c:1087
        #4  0x000055555559995c in panel_dir_list_callback (state=DIR_READ, 
data=0x555555704ac0) at ./src/filemanager/panel.c:4359
        #5  0x00005555555fdff7 in dir_list_load (list=0x555555801688, 
vpath=0x5555557f5020, sort=0x5555555fccec <sort_name>, sort_op=0x555555801760, 
filter=0x5555558017c0) at ./src/filemanager/dir.c:670
        #6  0x000055555559a1b7 in panel_sized_with_dir_new 
(panel_name=0x5555556784aa "New Right Panel", y=0, x=0, lines=0, cols=0, 
vpath=0x0) at ./src/filemanager/panel.c:4612
        #7  0x000055555558d975 in panel_sized_new (panel_name=0x5555556784aa 
"New Right Panel", y=0, x=0, lines=0, cols=0) at 
../../src/filemanager/panel.h:272
        #8  0x000055555558ed29 in restore_into_right_dir_panel (idx=1, 
last_was_panel=0, y=0, x=0, lines=0, cols=0) at ./src/filemanager/layout.c:668
        #9  0x000055555558fca3 in create_panel (num=1, type=view_listing) at 
./src/filemanager/layout.c:1189
        #10 0x000055555558279a in create_panels () at 
./src/filemanager/filemanager.c:658
        #11 0x0000555555582ee3 in create_file_manager () at 
./src/filemanager/filemanager.c:911
        #12 0x0000555555584bed in do_nc () at 
./src/filemanager/filemanager.c:1840
        #13 0x0000555555570a92 in main (argc=1, argv=0x7fffffffe248) at 
./src/main.c:458
        (gdb) 

It's dlg_run() that will put the file browser into the top_dlg list; but
top_dlg is still empty in the above backtrace, so no MSG_RESIZE messages
are sent.  If SIGWINCH comes at the "expected" time, I see this:
        (gdb) bt
        #0  send_message (w=0x5555557f5a80, sender=0x0, msg=MSG_RESIZE, parm=0, 
data=0x0) at ../../lib/widget/widget-common.h:250
        #1  0x0000555555655e79 in dialog_switch_resize (d=0x5555557f5a80) at 
./lib/widget/dialog-switch.c:136
        #2  0x00005555556568cc in dialog_change_screen_size () at 
./lib/widget/dialog-switch.c:447
        #3  0x0000555555657020 in frontend_dlg_run (h=0x5555557f5a80) at 
./lib/widget/dialog.c:293
        #4  0x0000555555657ac2 in dlg_run (h=0x5555557f5a80) at 
./lib/widget/dialog.c:574
        #5  0x0000555555584bff in do_nc () at 
./src/filemanager/filemanager.c:1841
        #6  0x0000555555570a92 in main (argc=1, argv=0x7fffffffe248) at 
./src/main.c:458
        (gdb) 

Simply sticking a "return" at the top of rotate_dash() makes the problem
unreproducible, and gives me a PASS from the test case.  Something like
a global 'is_ready' flag might be a better way to do it; or just ensure
dialog_change_screen_size() doesn't flush the pipe if the dialog list is
empty.

While debugging this, I noticed a related bug in toggle_subshell(),
which has this code:
        was_sigwinch = tty_got_winch ();
        tty_flush_winch ();

If a SIGWINCH were handled after setting was_sigwinch to 0 but before
flushing the pipe, the SIGWINCH would be missed.  I never saw it happen,
but it could be easily fixed by replacing that code with:
        was_sigwinch = tty_flush_winch ();
and making that function return the appropriate boolean value.

-- Michael

Attachment: signature.asc
Description: PGP signature

Reply via email to