Dominique Pelle wrote:
> Attached patch fixes a race condition which causes Vim to hang > when resuming (with fg) after having suspended Vim with CTRL-Z. > Bug does not happen 100% of the time, but once in a while. I > can reproduce the bug with Vim-7.2.121 in a xterm on Linux x86 > after doing > > CTRL-Z > fg > CTRL-Z > fg > , etc, ... several times until Vim hangs. > > Pressing CTRL-C is a workaround when it hangs. > > See also Ubuntu bug https://bugs.launchpad.net/bugs/291373 > > Bug only happens when configure script defined -D_REENTRANT > which happens at least when I configure Vim as follows: > > ./configure --enable-tclinterp --enable-rubyinterp \ > --enable-perlinterp --enable-pythoninterp \ > --with-features=huge --enable-gui=gnome2 > > The problem happens I think because the following 2 lines > in os_unix.c in mch_suspect() have a race condition: > > if (!sigcont_received) > pause(); > > If the signal is handled _after_ the test of sigcont_received > variable but _before_ pause() is executed, then pause() will > wait for ever since signal already happened. > > Also I think that the variable sigcont_received should also be > declared volatile since it's modified by a signal handler. > > Attached patch fixes the race condition by waiting until > sigcont_received is set without calling pause(): > > long wait; > for (wait = 0; !sigcont_received && wait <= 3L; wait++) > /* Loop is not entered most of the time */ > mch_delay(wait, FALSE); > > Note that most of the time the loop does not even need > to sleep() at all (sigcont_received is already set most of > the time before entering the loop). And when it it sleeps, > a sleep(0) seems always enough in practice. I've put > debug printf() after the loop that waits for sigcont_received > and I see this when doing several suspend (CTRL-Z, fg): > > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=1 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=1 > **** wait=0 > **** wait=0 > **** wait=0 > **** wait=0 > > Notice that in 2 occasions, wait was 1 (meaning that the loop > iterated once with a sleep of 0 (yielding the CPU which is > enough to get the signal handled). Makes sense. Perhaps pause() does some work that increases the change for the race condition to actually happen (e.g., a aquiring a lock). One problem: the Vim code doesn't use volatile yet. I don't think every C compiler supports it, thus this requires adding a configure check. AC_C_VOLATILE will do. -- hundred-and-one symptoms of being an internet addict: 117. You are more comfortable typing in html. /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org /// --~--~---------~--~----~------------~-------~--~----~ You received this message from the "vim_dev" maillist. For more information, visit http://www.vim.org/maillist.php -~----------~----~----~----~------~----~------~--~---
