emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: wait_reading_process_ouput hangs in certain cases (w/ patches)


From: Paul Eggert
Subject: Re: wait_reading_process_ouput hangs in certain cases (w/ patches)
Date: Tue, 14 Nov 2017 13:54:35 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0

On 11/14/2017 08:23 AM, Eli Zaretskii wrote:
And also the problem you are talking about, because I'm not sure I  > 
understand it well enough.
I doubt whether anyone understands the problem well enough, which is why I have been asking questions about the proposed solution - which as far as I can see, is more of a band-aid rather than a real fix. To help move this forward, I just reread the original bug report here:

https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00743.html

and I have some further questions that may help understand what's going on. The bug report said:

flyspell.el ... waits for output from its spellchecker process > through accept-process-output and specifies that specific process as
> wait_proc. Now depending on timing (race), > wait_reading_process_output can call the pending timers... which in > turn can call accept-process-output again. This almost always leads > to the spellchecker output being read back in full, so there is no > more data left to be read. Thus the original accept-process-output, > which called wait_reading_process_output, will wait for the data to > become available forever since it has no way to know that those have > already been read. When this happens, it appears that the original accept-process-output acted by calling wait_reading_process (0, 0, 0, 0, Qnil, PROC, 0) where PROC is the ispell-process. First, is that correct? (If not, my remaining questions may be a wild goose chase....)

This meant the original wait_reading_process did the following: set wait = INFINITY, run the timers (which apparently call wait_reading_process recursively), then check whether update_tick != process_tick (line 5182 of process.c in commit 79108894dbcd642121466bb6af6c98c6a56e9233). Is update_tick equal to process_tick in the problematic call? I'll assume so, but please check this. (If not, my remaining questions may need to be changed.)

Next, the original wait_reading_process output checks whether wait_proc->raw_status_new is nonzero (line 5210). Is it nonzero? For now, I'll assume it is zero. (If not, my remaining questions may need to be changed.)

Next, the original wait_reading_process_output checks whether (! EQ (wait_proc->status, Qrun) && ! connecting_status (wait_proc->status)) (line 5213). Does this check succeed? For now, I'll assume this check returns false. (If not, then we need to understand why.)

Next, the original wait_reading_process_output recomputes the input wait masks, sets check_delay = 0, check_write = true, no_avail = 0, timeout = timer_delay (line 5355), and so forth. This means it wiil call select with a nonzero timeout, even though we don't want it to do that: we want wait_reading_process_output to return 0, because it attempted to receive input but got none.

The changes you're proposing essentially kick the code so that it pretends that it read some bytes, even though it didn't (because the bytes were actually read and processed by a subroutine), causing it to exit the loop (and return nonzero instead of zero -- why?). But isn't this kick what the update_tick != process_tick (line 5182) check is supposed to be doing? And if so, why isn't that check working for your case? Is it because the code is forgetting to increment a tick count?

This above sort of reasoning is the sort of thing that needs to be done with this sort of change to such an intricate part of the Emacs code.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]