irssi-import / bugs.irssi.org

bugs.irssi.org archive
https://github.com/irssi/irssi/issues
0 stars 0 forks source link

missed redraws due to concurrency error #827

Open irssibot opened 12 years ago

irssibot commented 12 years ago

There's a concurrency error between sig_winch() and check_dirty() that results in the screen not being redrawn when it should be.

To be more precise, in src/fe-text/irssi.c we have

    void irssi_set_dirty(void)
    {
        dirty = TRUE;
    }

    static void dirty_check(void)
    {
        if (!dirty || dummy)
            return;

        // ... Do redraw stuff ...

        dirty = FALSE;
    }

and in src/fe-text/term.c we have

    static void sig_winch(int p)
    {
        irssi_set_dirty();
        resize_dirty = TRUE;
    }

The problem is that dirty_check() might be in the middle of a redraw when the winch signal comes in, at which point sig_winch sets dirty = TRUE. Then, after dirty_check() is done with its (now out of date) redraw, it sets dirty back to FALSE. Hence the required redraw never occurs.

I've fixed this for now (patch attached) by moving dirty = FALSE in dirty_check to before the redraw stuff takes place, reasoning that a redundant redraw is less worse than a missed redraw (which leaves the screen in a mess on my machines).

I guess really there should be some locking on the dirty variable, but maybe that's a bit heavy weight...

irssibot commented 12 years ago

dirty_check.patch

diff -aur irssi-0.8.15/src/fe-text/irssi.c irssi-0.8.15-patched/src/fe-text/irssi.c
--- irssi-0.8.15/src/fe-text/irssi.c    2010-04-03 18:19:42.000000000 +0200
+++ irssi-0.8.15-patched/src/fe-text/irssi.c    2011-12-22 21:22:11.000000000 +0100
@@ -114,6 +114,8 @@
    if (!dirty || dummy)
        return;

+        dirty = FALSE;
+
         term_resize_dirty();

    if (full_redraw) {
@@ -131,8 +133,6 @@
    mainwindows_redraw_dirty();
         statusbar_redraw_dirty();
    term_refresh(NULL);
-
-        dirty = FALSE;
 }

 static void textui_init(void)