Subject: bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs

From: Gemini Lasswell <[email-masked]>
Date: Sat, 25 Aug 2018 14:53:24 -0700

Hello Michael,

Michael Albinus <[email-masked]> writes:

> Tramp propagates all signals to the main thread, otherwise they are not
> visible. But this might be problematic for the quit signal.

Actually it's problematic for all signals.  I'm traveling this weekend
and came up with a no-network-required way to reproduce an Emacs
exit when the main thread is signaled:

Evaluate the following:

(defun my-thread-func ()
  (sleep-for 5)
  (thread-signal main-thread 'error "message"))
(make-thread #'my-thread-func)

Then, within 5 seconds, type C-x C-f.  Wait a few seconds.
Result: Emacs aborts.

Emacs aborting in this case is arguably by design, not a bug.

But even if we change it so the main thread does not kill Emacs if
signaled while waiting for input, signaling the main thread on a child
thread error is still problematic from a user friendliness point of
view.  Imagine I'm somewhere with a slow network connection, and start
an asynchronous find-file.  I know the file is large, and it will take a
while, so I bring up a message buffer, type an email and C-c C-c, so the
main thread starts a network connection with my email server.  That
causes it to yield to the find-file thread, which encounters an error.
If that error is signaled to the main thread, it will interrupt the
sending of the message.

> I could not reproduce the problem myself, but this was said already by
> Gemini that it isn't easy. The following patch does not propagate the
> quit (and debug) signals do the main thread. Does it help?

I can try it on Monday when I return, but I'm thinking it's the wrong
approach. 

Instead, maybe find-file-with-threads should wrap its body with
something similar to with-demoted-errors.  I say similar because I'm not
sure the debug-on-error behavior is right for this case.

Another thought is that the thread-last-error function is currently not
very useful, because its caller has no way to tell which thread had the
error, and if more than one thread has an error, only the most recent is
saved.  An improvement would be to give it an optional argument, a
thread, and have it return the error that made that thread inactive, if
there was one.  (This could probably replace the recently added cleanup
argument.)

Then asynchronous find-file could make a list of the threads it starts,
and start either a timer or another thread to periodically check that list
of threads, look for those which recently became inactive and report any
errors with 'message', or wait until all threads are done and print a
summary of successes and failures.