* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs @ 2018-08-22 18:19 Gemini Lasswell 2018-08-22 18:46 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Gemini Lasswell @ 2018-08-22 18:19 UTC (permalink / raw) To: 32502 This bug report is against the feature/tramp-thread-safe branch, 162353c45c. C-g typed while Tramp is opening multiple remote files asynchronously will sometimes cause Emacs to abort. It's probably dependent on the timing of the C-g, and seems to either happen the first time I try C-g or not at all. I'm typing C-g fairly soon after RET, but not as fast as I possibly could. The remote machine is on the local network and I'm running Emacs on a laptop with a wireless network connection. So far I've reproduced the bug twice in about 8 attempts. I currently have it in the debugger. To reproduce, with emacs -Q and the Emacs source tree stored on a remote machine: C-x & C-x C-f /scp:server:src/emacs/lisp/emacs-lisp/*.el RET C-g Result: #0 terminate_due_to_signal (sig=sig@entry=6, backtrace_limit=backtrace_limit@entry=40) at emacs.c:368 #1 0x0000000000511833 in emacs_abort () at sysdep.c:2426 #2 0x000000000057114d in signal_or_quit (error_symbol=XIL(0xaaa0), data=XIL(0), keyboard_quit=keyboard_quit@entry=false) at eval.c:1612 #3 0x000000000057115b in Fsignal (error_symbol=<optimized out>, data=<optimized out>) at eval.c:1582 #4 0x00000000005d5555 in post_acquire_global_lock (self=self@entry=0xc19320 <main_thread>) at thread.c:93 #5 0x00000000005d578a in acquire_global_lock (self=0xc19320 <main_thread>) at thread.c:101 #6 really_call_select (arg=0x7ffe202d8ab0) at thread.c:582 #7 0x00000000005d64e9 in thread_select (func=<optimized out>, max_fds=max_fds@entry=11, rfds=rfds@entry=0x7ffe202d8b90, wfds=<optimized out>, efds=efds@entry=0x0, timeout=timeout@entry=0x7ffe202d91b0, sigmask=0x0) at thread.c:602 #8 0x00000000005f1f44 in xg_select (fds_lim=11, rfds=rfds@entry=0x7ffe202d92b0, wfds=wfds@entry=0x7ffe202d9330, efds=efds@entry=0x0, timeout=timeout@entry=0x7ffe202d91b0, sigmask=sigmask@entry=0x0) at xgselect.c:117 #9 0x00000000005b7328 in wait_reading_process_output (time_limit=time_limit@entry=30, nsecs=nsecs@entry=0, read_kbd=read_kbd@entry=-1, do_display=do_display@entry=true, wait_for_cell=wait_for_cell@entry=XIL(0), wait_proc=wait_proc@entry=0x0, just_wait_proc=0) at process.c:5384 #10 0x0000000000424000 in sit_for (timeout=<optimized out>, reading=reading@entry=true, display_option=display_option@entry=1) at dispnew.c:5801 #11 0x00000000005042c6 in read_char (commandflag=commandflag@entry=1, map=map@entry=XIL(0x4d90c43), prev_event=XIL(0), used_mouse_menu=used_mouse_menu@entry=0x7ffe202d9bab, end_time=end_time@entry=0x0) at keyboard.c:2688 #12 0x000000000050491b in read_key_sequence (keybuf=keybuf@entry=0x7ffe202d9ce0, prompt=prompt@entry=XIL(0), dont_downcase_last=dont_downcase_last@entry=false, can_return_switch_frame=can_return_switch_frame@entry=true, fix_current_buffer=fix_current_buffer@entry=true, prevent_redisplay=prevent_redisplay@entry=false) at keyboard.c:9108 #13 0x00000000005062fa in command_loop_1 () at keyboard.c:1338 #14 0x000000000056f6ef in internal_condition_case (bfun=bfun@entry=0x506100 <command_loop_1>, handlers=handlers@entry=XIL(0x5340), hfun=hfun@entry=0x4fae20 <cmd_error>) at eval.c:1349 #15 0x00000000004f77e8 in command_loop_2 (ignore=ignore@entry=XIL(0)) at keyboard.c:1079 #16 0x000000000056f653 in internal_catch (tag=tag@entry=XIL(0xc990), func=func@entry=0x4f77c0 <command_loop_2>, arg=arg@entry=XIL(0)) at eval.c:1114 #17 0x00000000004f7776 in command_loop () at keyboard.c:1058 #18 0x00000000004faa0f in recursive_edit_1 () at keyboard.c:703 #19 0x00000000004fad48 in Frecursive_edit () at keyboard.c:774 #20 0x000000000041a353 in main (argc=<optimized out>, argv=0x7ffe202da098) at emacs.c:1756 In GNU Emacs 27.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.28) of 2018-08-21 built on sockeye Repository revision: 162353c45cf7ae8c5626a5062c247a793e30e7d0 Windowing system distributor 'The X.Org Foundation', version 11.0.11906000 System Description: NixOS 18.03.git.bd06547 (Impala) Recent messages: For information about GNU Emacs and the GNU system, type C-h C-a. Configured using: 'configure --prefix=/home/gem/src/emacs/tramp/bin --with-modules --with-x-toolkit=gtk3 --with-xft --config-cache' Configured features: XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND DBUS GSETTINGS NOTIFY LIBSELINUX GNUTLS LIBXML2 FREETYPE XFT ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 MODULES THREADS LCMS2 GMP Important settings: value of $EMACSLOADPATH: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t line-number-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug message rmc puny seq byte-opt gv bytecomp byte-compile cconv dired dired-loaddefs format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg epg-config gnus-util rmail rmail-loaddefs mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils elec-pair time-date mule-util tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting move-toolbar gtk x-toolkit x multi-tty make-network-process emacs) Memory information: ((conses 16 94963 7770) (symbols 48 20145 1) (strings 32 28303 1519) (string-bytes 1 756774) (vectors 16 14934) (vector-slots 8 508714 14278) (floats 8 48 69) (intervals 56 208 0) (buffers 992 11)) ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 18:19 bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs Gemini Lasswell @ 2018-08-22 18:46 ` Eli Zaretskii 2018-08-22 19:08 ` Eli Zaretskii 2018-08-22 21:12 ` Gemini Lasswell 0 siblings, 2 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-08-22 18:46 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502 > From: Gemini Lasswell <gazally@runbox.com> > Date: Wed, 22 Aug 2018 11:19:34 -0700 > > To reproduce, with emacs -Q and the Emacs source tree stored on a remote > machine: > > C-x & C-x C-f /scp:server:src/emacs/lisp/emacs-lisp/*.el RET > C-g > > Result: > > #0 terminate_due_to_signal (sig=sig@entry=6, backtrace_limit=backtrace_limit@entry=40) at emacs.c:368 > #1 0x0000000000511833 in emacs_abort () at sysdep.c:2426 > #2 0x000000000057114d in signal_or_quit (error_symbol=XIL(0xaaa0), data=XIL(0), keyboard_quit=keyboard_quit@entry=false) at eval.c:1612 In frame #2, which one of these 2 conditions caused the abort: if (gc_in_progress || waiting_for_input) emacs_abort (); > #3 0x000000000057115b in Fsignal (error_symbol=<optimized out>, data=<optimized out>) at eval.c:1582 > #4 0x00000000005d5555 in post_acquire_global_lock (self=self@entry=0xc19320 <main_thread>) at thread.c:93 And in frame #4, what is current_thread->error_symbol? Thanks. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 18:46 ` Eli Zaretskii @ 2018-08-22 19:08 ` Eli Zaretskii 2018-08-22 19:23 ` Michael Albinus 2018-08-25 10:53 ` Michael Albinus 2018-08-22 21:12 ` Gemini Lasswell 1 sibling, 2 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-08-22 19:08 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > Date: Wed, 22 Aug 2018 21:46:42 +0300 > From: Eli Zaretskii <eliz@gnu.org> > Cc: 32502@debbugs.gnu.org > > > #3 0x000000000057115b in Fsignal (error_symbol=<optimized out>, data=<optimized out>) at eval.c:1582 > > #4 0x00000000005d5555 in post_acquire_global_lock (self=self@entry=0xc19320 <main_thread>) at thread.c:93 > > And in frame #4, what is current_thread->error_symbol? Michael, unless I'm missing something, it sounds like Tramp signals the main thread in this scenario. (current_thread->error_symbol is only set by thread-signal.) Is that really necessary? If so, can you describe why you needed to signal the main thread, while it was waiting for input? ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 19:08 ` Eli Zaretskii @ 2018-08-22 19:23 ` Michael Albinus 2018-08-25 10:53 ` Michael Albinus 1 sibling, 0 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-22 19:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: Hi Eli, > Michael, unless I'm missing something, it sounds like Tramp signals > the main thread in this scenario. (current_thread->error_symbol is > only set by thread-signal.) Is that really necessary? If so, can you > describe why you needed to signal the main thread, while it was > waiting for input? Will work on this over the weekend, there's no time left until. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 19:08 ` Eli Zaretskii 2018-08-22 19:23 ` Michael Albinus @ 2018-08-25 10:53 ` Michael Albinus 2018-08-25 12:42 ` Eli Zaretskii 2018-08-25 21:53 ` Gemini Lasswell 1 sibling, 2 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-25 10:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 [-- Attachment #1: Type: text/plain, Size: 1184 bytes --] Eli Zaretskii <eliz@gnu.org> writes: Hi Eli, >> > #3 0x000000000057115b in Fsignal (error_symbol=<optimized out>, >> > data=<optimized out>) at eval.c:1582 >> > #4 0x00000000005d5555 in post_acquire_global_lock >> > (self=self@entry=0xc19320 <main_thread>) at thread.c:93 >> >> And in frame #4, what is current_thread->error_symbol? > > Michael, unless I'm missing something, it sounds like Tramp signals > the main thread in this scenario. (current_thread->error_symbol is > only set by thread-signal.) Is that really necessary? If so, can you > describe why you needed to signal the main thread, while it was > waiting for input? Tramp propagates all signals to the main thread, otherwise they are not visible. But this might be problematic for the quit signal. 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? However, if we apply this I don't know how to quit (let's say) 250 threads. One quit signal is good for one thread only. I believe we need also a mechanism to quit many threads at once. Best regards, Michael. [-- Attachment #2: Type: text/plain, Size: 1022 bytes --] diff --git a/lisp/tramp.el b/lisp/tramp.el index c913640e..3a09674c 100644 --- a/lisp/tramp.el +++ b/lisp/tramp.el @@ -2342,8 +2342,9 @@ If Emacs is compiled --with-threads, the body is protected by a mutex." (tramp-message v 1 "Interrupt received in operation %s" (cons operation args))) - ;; Propagate the quit signal. - (tramp-compat-signal (car err) (cdr err))) + ;; Propagate the signal. We do not want this + ;; to go to the main thread. + (signal (car err) (cdr err))) ;; When we are in completion mode, some failed ;; operations shall return at least a default @@ -2361,7 +2362,7 @@ If Emacs is compiled --with-threads, the body is protected by a mutex." (memq operation '(expand-file-name file-name-as-directory))) filename) - ;; Propagate the error. + ;; Propagate the error to the main thread. (t (tramp-compat-signal (car err) (cdr err)))))) ;; Nothing to do for us. However, since we are in ^ permalink raw reply related [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 10:53 ` Michael Albinus @ 2018-08-25 12:42 ` Eli Zaretskii 2018-08-25 15:52 ` Michael Albinus 2018-08-25 21:53 ` Gemini Lasswell 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-25 12:42 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Sat, 25 Aug 2018 12:53:02 +0200 > > > Michael, unless I'm missing something, it sounds like Tramp signals > > the main thread in this scenario. (current_thread->error_symbol is > > only set by thread-signal.) Is that really necessary? If so, can you > > describe why you needed to signal the main thread, while it was > > waiting for input? > > Tramp propagates all signals to the main thread, otherwise they are not > visible. Is that wise? It means that if a user is doing something in the main thread while the Tramp threads run asynchronously, the user's program will/might error out. > However, if we apply this I don't know how to quit (let's say) 250 > threads. One quit signal is good for one thread only. I believe we need > also a mechanism to quit many threads at once. I think we should simply make thread-signal a no-op when it signals the main thread during the time the main thread is waiting for input. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 12:42 ` Eli Zaretskii @ 2018-08-25 15:52 ` Michael Albinus 2018-08-25 16:07 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-25 15:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> From: Michael Albinus <michael.albinus@gmx.de> >> Cc: gazally@runbox.com, 32502@debbugs.gnu.org >> Date: Sat, 25 Aug 2018 12:53:02 +0200 >> >> > Michael, unless I'm missing something, it sounds like Tramp signals >> > the main thread in this scenario. (current_thread->error_symbol is >> > only set by thread-signal.) Is that really necessary? If so, can you >> > describe why you needed to signal the main thread, while it was >> > waiting for input? >> >> Tramp propagates all signals to the main thread, otherwise they are not >> visible. > > Is that wise? It means that if a user is doing something in the main > thread while the Tramp threads run asynchronously, the user's program > will/might error out. Perhaps not. But I didn't like that no Tramp error was visible from a thread. >> However, if we apply this I don't know how to quit (let's say) 250 >> threads. One quit signal is good for one thread only. I believe we need >> also a mechanism to quit many threads at once. > > I think we should simply make thread-signal a no-op when it signals > the main thread during the time the main thread is waiting for input. Perhaps. But I don't understand how this solves the problem (quitting several threads at once). Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 15:52 ` Michael Albinus @ 2018-08-25 16:07 ` Eli Zaretskii 2018-08-26 13:50 ` Gemini Lasswell 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-25 16:07 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Sat, 25 Aug 2018 17:52:34 +0200 > > > I think we should simply make thread-signal a no-op when it signals > > the main thread during the time the main thread is waiting for input. > > Perhaps. But I don't understand how this solves the problem (quitting > several threads at once). Well, you never want to end the main thread, do you? But perhaps I don't understand well enough the situation you are talking about. Can you describe in more detail when and why do you need to "quit several threads at once"? ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 16:07 ` Eli Zaretskii @ 2018-08-26 13:50 ` Gemini Lasswell 2018-08-30 9:24 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Gemini Lasswell @ 2018-08-26 13:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 32502, Michael Albinus Eli Zaretskii <eliz@gnu.org> writes: > > Well, you never want to end the main thread, do you? > > But perhaps I don't understand well enough the situation you are > talking about. Can you describe in more detail when and why do you > need to "quit several threads at once"? The ability to quit multiple threads at once also seems useful to me. One possibility would be if you do something like this, to open up all your project files at once: C-x & C-x f /scp:server:project/worktree_a/*.el RET And then after you press RET, realize that you meant to type worktree_b instead. Or after you press RET, realize that your network connection is too slow for what you've asked Emacs to do, making you decide you'd like it to give up. Or each of the threads starts reporting the same error, and you realize none of them are going to work, and you want to make the error spam stop so you can fix the problem. Right now the "Checking vc-registered" phase of multi-threaded find-file hogs the global lock and makes Emacs unusable for a while if you are loading many files at once; maybe that, or some other package in your config which wasn't written with threading in mind and gets called by your find-file threads, makes Emacs slow and goes on for too long, and you want to make it stop so you can do something else. C-g is probably not the solution to these situations and I'm not sure what is, but it would be nice to have some way to resolve them besides restarting Emacs. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-26 13:50 ` Gemini Lasswell @ 2018-08-30 9:24 ` Michael Albinus 2018-08-30 13:23 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 9:24 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502 Gemini Lasswell <gazally@runbox.com> writes: Hi Gemini, > The ability to quit multiple threads at once also seems useful to me. > > One possibility would be if you do something like this, to open up all > your project files at once: > > C-x & C-x f /scp:server:project/worktree_a/*.el RET > > And then after you press RET, realize that you meant to type worktree_b > instead. > > Or after you press RET, realize that your network connection is too slow > for what you've asked Emacs to do, making you decide you'd like it to > give up. > > Or each of the threads starts reporting the same error, and you realize > none of them are going to work, and you want to make the error spam stop > so you can fix the problem. > > Right now the "Checking vc-registered" phase of multi-threaded > find-file hogs the global lock and makes Emacs unusable for a while if > you are loading many files at once; maybe that, or some other package in > your config which wasn't written with threading in mind and gets called > by your find-file threads, makes Emacs slow and goes on for too long, > and you want to make it stop so you can do something else. > > C-g is probably not the solution to these situations and I'm not sure > what is, but it would be nice to have some way to resolve them besides > restarting Emacs. You could enhance your thread.el. In the list of threads, one could mark threads, and send all of them the quit signal via a new command. Likely, this should happen only if you are in the main thread. So we also need a command which lets you switch to the main thread, wherever you are. C-g could be good for this, but I don't know whether there are undesired side effects. Hmm, this is the bug report. Shall we discuss it on emacs-devel? Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 9:24 ` Michael Albinus @ 2018-08-30 13:23 ` Eli Zaretskii 2018-08-30 13:28 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-30 13:23 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: Eli Zaretskii <eliz@gnu.org>, 32502@debbugs.gnu.org > Date: Thu, 30 Aug 2018 11:24:00 +0200 > > So we also need a command which lets you switch to the main thread, > wherever you are. This would need some infrastructure that currently doesn't exist. Wed can tell the current thread to yield, but we have no way of designating another thread that will run when the first one yields. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 13:23 ` Eli Zaretskii @ 2018-08-30 13:28 ` Michael Albinus 0 siblings, 0 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-30 13:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> So we also need a command which lets you switch to the main thread, >> wherever you are. > > This would need some infrastructure that currently doesn't exist. Wed > can tell the current thread to yield, but we have no way of > designating another thread that will run when the first one yields. Of course. But in the "User interaction from multiple threads" thread there was also the proposal to delegate tasks from a thread to the main thread. So there seems to be also other use cases. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 10:53 ` Michael Albinus 2018-08-25 12:42 ` Eli Zaretskii @ 2018-08-25 21:53 ` Gemini Lasswell 2018-08-26 14:12 ` Eli Zaretskii 2018-08-29 16:01 ` Michael Albinus 1 sibling, 2 replies; 42+ messages in thread From: Gemini Lasswell @ 2018-08-25 21:53 UTC (permalink / raw) To: Michael Albinus; +Cc: 32502 Hello Michael, Michael Albinus <michael.albinus@gmx.de> 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. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 21:53 ` Gemini Lasswell @ 2018-08-26 14:12 ` Eli Zaretskii 2018-08-30 7:19 ` Michael Albinus 2018-08-29 16:01 ` Michael Albinus 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-26 14:12 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502, michael.albinus > From: Gemini Lasswell <gazally@runbox.com> > Cc: Eli Zaretskii <eliz@gnu.org>, 32502@debbugs.gnu.org > Date: Sat, 25 Aug 2018 14:53:24 -0700 > > (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. Yes. We could advise people not to do that, and we could ignore such signals in the code. > Instead, maybe find-file-with-threads should wrap its body with > something similar to with-demoted-errors. That is already happening, for some sense of "demoted-errors": a non-main thread that hits a fatal signal simply dies in silence. > 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.) We could indeed make the error bookkeeping more sphisticated. > 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. I don't think this will work, at least not literally as described, because (1) running timers in multithreaded environment is tricky -- you don't know which thread will run it, but more often that not it will be the main thread; and (2) only one thread runs at any given time, so making a thread that will periodically do something is not simple, as there's no guarantee it will indeed run with the requested periodicity. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-26 14:12 ` Eli Zaretskii @ 2018-08-30 7:19 ` Michael Albinus 2018-08-30 12:34 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 7:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Gemini Lasswell, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> 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.) > > We could indeed make the error bookkeeping more sphisticated. > >> 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. > > I don't think this will work, at least not literally as described, > because (1) running timers in multithreaded environment is tricky -- > you don't know which thread will run it, but more often that not it > will be the main thread; and (2) only one thread runs at any given > time, so making a thread that will periodically do something is not > simple, as there's no guarantee it will indeed run with the requested > periodicity. Instead of a timer, the asynchronous find-file could check for errors of the finished thread(s). A good point might be, when thread-join delivers the result(s). It was said earlier already (I believe), but I repeat it: thread-join should not only return the result, but should also propagate signals the thread has been trapped. It would be the responsibility of the calling code to ignore this information, or to propagate. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 7:19 ` Michael Albinus @ 2018-08-30 12:34 ` Michael Albinus 0 siblings, 0 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-30 12:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Gemini Lasswell, 32502 Michael Albinus <michael.albinus@gmx.de> writes: > Instead of a timer, the asynchronous find-file could check for errors of > the finished thread(s). A good point might be, when thread-join delivers > the result(s). > > It was said earlier already (I believe), but I repeat it: thread-join > should not only return the result, but should also propagate signals the > thread has been trapped. It would be the responsibility of the calling > code to ignore this information, or to propagate. I stay corrected: thread-join propagates also errors to the calling thread. I've modified Tramp not to propagate errors to the main thread. In find-file-noselect, thread-join is wrapped now by with-demoted-errors. Pushed to the feature/tramp-thread-safe branch. Gemini, could you pls check whether this works for you as expected? Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-25 21:53 ` Gemini Lasswell 2018-08-26 14:12 ` Eli Zaretskii @ 2018-08-29 16:01 ` Michael Albinus 2018-08-29 16:23 ` Eli Zaretskii 1 sibling, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-29 16:01 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502 Gemini Lasswell <gazally@runbox.com> writes: > Hello Michael, Hi Gemini, >> 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. For me, Emacs aborts even w/o any user action. Just waiting. > Emacs aborting in this case is arguably by design, not a bug. Why do you believe that aborting is by design? I would regard it as a bug. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 16:01 ` Michael Albinus @ 2018-08-29 16:23 ` Eli Zaretskii 2018-08-29 16:46 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-29 16:23 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: Eli Zaretskii <eliz@gnu.org>, 32502@debbugs.gnu.org > Date: Wed, 29 Aug 2018 18:01:02 +0200 > > > Emacs aborting in this case is arguably by design, not a bug. > > Why do you believe that aborting is by design? I would regard it as a bug. Because the code speaks for itself: static Lisp_Object signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) { [...] if (gc_in_progress || waiting_for_input) <<<<<<<<<<<<<<<<<<<<<<<< emacs_abort (); It could be that the reason for that is no longer valid when the signal was raised by another thread, via thread-signal. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 16:23 ` Eli Zaretskii @ 2018-08-29 16:46 ` Michael Albinus 2018-08-29 17:03 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-29 16:46 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> > Emacs aborting in this case is arguably by design, not a bug. >> >> Why do you believe that aborting is by design? I would regard it as a bug. > > Because the code speaks for itself: > > static Lisp_Object > signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) > { > [...] > if (gc_in_progress || waiting_for_input) <<<<<<<<<<<<<<<<<<<<<<<< > emacs_abort (); > > It could be that the reason for that is no longer valid when the > signal was raised by another thread, via thread-signal. But I haven't done any user input. I've evaluated the code snippet given by Gemini, and then I've done nothing. Emacs was idle I believe. And it aborted. I will bisect, in order to see where this bug comes from. Best regards, Michael? ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 16:46 ` Michael Albinus @ 2018-08-29 17:03 ` Eli Zaretskii 2018-08-29 17:15 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-29 17:03 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Wed, 29 Aug 2018 18:46:01 +0200 > > > static Lisp_Object > > signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit) > > { > > [...] > > if (gc_in_progress || waiting_for_input) <<<<<<<<<<<<<<<<<<<<<<<< > > emacs_abort (); > > > > It could be that the reason for that is no longer valid when the > > signal was raised by another thread, via thread-signal. > > But I haven't done any user input. I've evaluated the code snippet given > by Gemini, and then I've done nothing. Emacs was idle I believe. And it > aborted. That's just it, AFAIR: when Emacs is idle, the waiting_for_input flag is set. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 17:03 ` Eli Zaretskii @ 2018-08-29 17:15 ` Michael Albinus 2018-08-29 20:22 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-29 17:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> But I haven't done any user input. I've evaluated the code snippet given >> by Gemini, and then I've done nothing. Emacs was idle I believe. And it >> aborted. > > That's just it, AFAIR: when Emacs is idle, the waiting_for_input flag > is set. In this case, you cannot send a signal to the main thread ever. That contradicts the documentation in (info "(elisp) Basic Thread Functions") --8<---------------cut here---------------start------------->8--- Since signal handlers in Emacs are located in the main thread, a signal must be propagated there in order to become visible. The second ‘signal’ call let the thread die: (thread-signal main-thread 'error data) (signal 'error data) --8<---------------cut here---------------end--------------->8--- Let's see, what the bisecting tells us. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 17:15 ` Michael Albinus @ 2018-08-29 20:22 ` Michael Albinus 2018-08-29 20:57 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-29 20:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Michael Albinus <michael.albinus@gmx.de> writes: > Eli Zaretskii <eliz@gnu.org> writes: > >>> But I haven't done any user input. I've evaluated the code snippet given >>> by Gemini, and then I've done nothing. Emacs was idle I believe. And it >>> aborted. >> >> That's just it, AFAIR: when Emacs is idle, the waiting_for_input flag >> is set. > > Let's see, what the bisecting tells us. Emacs started to abort with the shown example with commit 798cbac170. Well, this commit is from me ... Will continue tomorrow understanding what's up. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 20:22 ` Michael Albinus @ 2018-08-29 20:57 ` Michael Albinus 2018-08-30 2:36 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-29 20:57 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Michael Albinus <michael.albinus@gmx.de> writes: > Emacs started to abort with the shown example with commit > 798cbac170. Well, this commit is from me ... This commit introduced the variable main-thread. Before, the thred-signal call couldn't deliver a signal to the main thread, Emacs couldn't abort. So it looks like you are right: we cannot send signals to the main thread. Is this acceptable? Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-29 20:57 ` Michael Albinus @ 2018-08-30 2:36 ` Eli Zaretskii 2018-08-30 7:09 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-30 2:36 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Wed, 29 Aug 2018 22:57:24 +0200 > > This commit introduced the variable main-thread. Before, the > thred-signal call couldn't deliver a signal to the main thread, Emacs > couldn't abort. > > So it looks like you are right: we cannot send signals to the main > thread. Is this acceptable? Yes, I think so, but let's document that. Thanks. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 2:36 ` Eli Zaretskii @ 2018-08-30 7:09 ` Michael Albinus 2018-08-30 13:18 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 7:09 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> So it looks like you are right: we cannot send signals to the main >> thread. Is this acceptable? > > Yes, I think so, but let's document that. Sounds to me like a serious restriction. When something happens in a thread, I want to know it. There isn't even a message about the error. > Thanks. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 7:09 ` Michael Albinus @ 2018-08-30 13:18 ` Eli Zaretskii 2018-08-30 13:32 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-30 13:18 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Thu, 30 Aug 2018 09:09:42 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> So it looks like you are right: we cannot send signals to the main > >> thread. Is this acceptable? > > > > Yes, I think so, but let's document that. > > Sounds to me like a serious restriction. When something happens in a > thread, I want to know it. There isn't even a message about the error. If we want to announce the errors to the main thread, we can use methods other than signaling an error. For example, we could inject a special event into the input queue, similarly to how we produce help-echo and other special events. Fsignal is a very blunt weapon, its main effect is to throw to top level. Why would we want to do that _in_the_main_thread_ when the problem happened in another thread? That's disruptive, and could even mean that the user will lose their edits. Not nice, IMO. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 13:18 ` Eli Zaretskii @ 2018-08-30 13:32 ` Michael Albinus 2018-08-30 13:51 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 13:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> >> So it looks like you are right: we cannot send signals to the main >> >> thread. Is this acceptable? >> > >> > Yes, I think so, but let's document that. I'm just doing it. >> Sounds to me like a serious restriction. When something happens in a >> thread, I want to know it. There isn't even a message about the error. > > If we want to announce the errors to the main thread, we can use > methods other than signaling an error. For example, we could inject > a special event into the input queue, similarly to how we produce > help-echo and other special events. I'm just changing thread-signal such a way that it ignores silently signals sent to the main thread. Shall I implement this event injection instead? And what shall be done with this event in the main thread? Just writing an error message, or some kind of handling? Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 13:32 ` Michael Albinus @ 2018-08-30 13:51 ` Eli Zaretskii 2018-08-30 13:59 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-30 13:51 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Thu, 30 Aug 2018 15:32:58 +0200 > > > If we want to announce the errors to the main thread, we can use > > methods other than signaling an error. For example, we could inject > > a special event into the input queue, similarly to how we produce > > help-echo and other special events. > > I'm just changing thread-signal such a way that it ignores silently > signals sent to the main thread. Shall I implement this event injection > instead? I don't know. I guess it depends on how important is it to show the errors nicely. You could leave signals for now and use the events idea later as an enhancement. > And what shall be done with this event in the main thread? Just writing > an error message, or some kind of handling? Yes, displaying a message would be a good starting point, I think. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 13:51 ` Eli Zaretskii @ 2018-08-30 13:59 ` Michael Albinus 2018-08-30 16:48 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 13:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> I'm just changing thread-signal such a way that it ignores silently >> signals sent to the main thread. Shall I implement this event injection >> instead? > > I don't know. I guess it depends on how important is it to show the > errors nicely. You could leave signals for now and use the events > idea later as an enhancement. I will see how easy it is. I have experience with dbus-event and file-notify-event; it shouldn't too hard for me to implement thread-event. >> And what shall be done with this event in the main thread? Just writing >> an error message, or some kind of handling? > > Yes, displaying a message would be a good starting point, I think. Since special events have their own handler, it will be simple to change later. Will start with echoing the error message. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 13:59 ` Michael Albinus @ 2018-08-30 16:48 ` Michael Albinus 2018-08-30 17:44 ` Eli Zaretskii 2018-08-30 19:29 ` Gemini Lasswell 0 siblings, 2 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-30 16:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 [-- Attachment #1: Type: text/plain, Size: 935 bytes --] Michael Albinus <michael.albinus@gmx.de> writes: >>> I'm just changing thread-signal such a way that it ignores silently >>> signals sent to the main thread. Shall I implement this event injection >>> instead? >> >> I don't know. I guess it depends on how important is it to show the >> errors nicely. You could leave signals for now and use the events >> idea later as an enhancement. > > I will see how easy it is. I have experience with dbus-event and > file-notify-event; it shouldn't too hard for me to implement thread-event. > >>> And what shall be done with this event in the main thread? Just writing >>> an error message, or some kind of handling? >> >> Yes, displaying a message would be a good starting point, I think. > > Since special events have their own handler, it will be simple to change > later. Will start with echoing the error message. Appended is a first implementation. Comments? Best regards, Michael. [-- Attachment #2: Type: text/plain, Size: 5428 bytes --] diff --git a/doc/lispref/threads.texi b/doc/lispref/threads.texi index 58a3a918ef..9830198411 100644 --- a/doc/lispref/threads.texi +++ b/doc/lispref/threads.texi @@ -88,14 +88,8 @@ Basic Thread Functions @code{condition-wait}, or @code{thread-join}; @code{thread-signal} will unblock it. -Since signal handlers in Emacs are located in the main thread, a -signal must be propagated there in order to become visible. The -second @code{signal} call let the thread die: - -@example -(thread-signal main-thread 'error data) -(signal 'error data) -@end example +If @var{thread} is the main thread, the signal is not propagated +there. Instead, it is shown as message in the main thread. @end defun @defun thread-yield diff --git a/src/keyboard.c b/src/keyboard.c index 7fafb41fcc..008d3b9d7c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2827,6 +2827,9 @@ read_char (int commandflag, Lisp_Object map, #endif #ifdef USE_FILE_NOTIFY || EQ (XCAR (c), Qfile_notify) +#endif +#ifdef THREADS_ENABLED + || EQ (XCAR (c), Qthread_event) #endif || EQ (XCAR (c), Qconfig_changed_event)) && !end_time) @@ -3739,7 +3742,7 @@ kbd_buffer_get_event (KBOARD **kbp, } #endif /* subprocesses */ -#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY +#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED if (noninteractive /* In case we are running as a daemon, only do this before detaching from the terminal. */ @@ -3750,7 +3753,7 @@ kbd_buffer_get_event (KBOARD **kbp, *kbp = current_kboard; return obj; } -#endif /* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY */ +#endif /* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY && !defined THREADS_ENABLED */ /* Wait until there is input available. */ for (;;) @@ -3900,6 +3903,9 @@ kbd_buffer_get_event (KBOARD **kbp, #ifdef HAVE_DBUS case DBUS_EVENT: #endif +#ifdef THREADS_ENABLED + case THREAD_EVENT: +#endif #ifdef HAVE_XWIDGETS case XWIDGET_EVENT: #endif @@ -5983,6 +5989,13 @@ make_lispy_event (struct input_event *event) } #endif /* HAVE_DBUS */ +#ifdef THREADS_ENABLED + case THREAD_EVENT: + { + return Fcons (Qthread_event, event->arg); + } +#endif /* THREADS_ENABLED */ + #ifdef HAVE_XWIDGETS case XWIDGET_EVENT: { @@ -11078,6 +11091,10 @@ syms_of_keyboard (void) DEFSYM (Qdbus_event, "dbus-event"); #endif +#ifdef THREADS_ENABLED + DEFSYM (Qthread_event, "thread-event"); +#endif + #ifdef HAVE_XWIDGETS DEFSYM (Qxwidget_event, "xwidget-event"); #endif @@ -11929,6 +11946,12 @@ keys_of_keyboard (void) "dbus-handle-event"); #endif +#ifdef THREADS_ENABLED + /* Define a special event which is raised for thread signals. */ + initial_define_lispy_key (Vspecial_event_map, "thread-event", + "thread-handle-event"); +#endif + #ifdef USE_FILE_NOTIFY /* Define a special event which is raised for notification callback functions. */ diff --git a/src/termhooks.h b/src/termhooks.h index 160bd2f480..8b5f648b43 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -222,6 +222,10 @@ enum event_kind , DBUS_EVENT #endif +#ifdef THREADS_ENABLED + , THREAD_EVENT +#endif + , CONFIG_CHANGED_EVENT #ifdef HAVE_NTGUI diff --git a/src/thread.c b/src/thread.c index 1c73d93865..0234f65e02 100644 --- a/src/thread.c +++ b/src/thread.c @@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include "process.h" #include "coding.h" #include "syssignal.h" +#include "keyboard.h" static struct thread_state main_thread; @@ -34,7 +35,6 @@ static struct thread_state *all_threads = &main_thread; static sys_mutex_t global_lock; -extern int poll_suppress_count; extern volatile int interrupt_input_blocked; \f @@ -863,7 +863,8 @@ DEFUN ("thread-signal", Fthread_signal, Sthread_signal, 3, 3, 0, This acts like `signal', but arranges for the signal to be raised in THREAD. If THREAD is the current thread, acts just like `signal'. This will interrupt a blocked call to `mutex-lock', `condition-wait', -or `thread-join' in the target thread. */) +or `thread-join' in the target thread. +Signals to the main thread are ignored quietly. */) (Lisp_Object thread, Lisp_Object error_symbol, Lisp_Object data) { struct thread_state *tstate; @@ -874,13 +875,29 @@ or `thread-join' in the target thread. */) if (tstate == current_thread) Fsignal (error_symbol, data); - /* What to do if thread is already signaled? */ - /* What if error_symbol is Qnil? */ - tstate->error_symbol = error_symbol; - tstate->error_data = data; + if (main_thread_p (tstate)) + { + /* Construct an event. */ + struct input_event event; + EVENT_INIT (event); + event.kind = THREAD_EVENT; + event.frame_or_window = Qnil; + event.arg = list3 (Fcurrent_thread (), error_symbol, data); + + /* Store it into the input event queue. */ + kbd_buffer_store_event (&event); + } + + else + { + /* What to do if thread is already signaled? */ + /* What if error_symbol is Qnil? */ + tstate->error_symbol = error_symbol; + tstate->error_data = data; - if (tstate->wait_condvar) - flush_stack_call_func (thread_signal_callback, tstate); + if (tstate->wait_condvar) + flush_stack_call_func (thread_signal_callback, tstate); + } return Qnil; } ^ permalink raw reply related [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 16:48 ` Michael Albinus @ 2018-08-30 17:44 ` Eli Zaretskii 2018-08-30 19:30 ` Michael Albinus 2018-08-30 19:29 ` Gemini Lasswell 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-30 17:44 UTC (permalink / raw) To: Michael Albinus; +Cc: gazally, 32502 > From: Michael Albinus <michael.albinus@gmx.de> > Cc: gazally@runbox.com, 32502@debbugs.gnu.org > Date: Thu, 30 Aug 2018 18:48:19 +0200 > > Appended is a first implementation. Comments? Looks good, thanks. > +If @var{thread} is the main thread, the signal is not propagated > +there. Instead, it is shown as message in the main thread. Maybe I'm missing something, but where's the code which shows this message? > @@ -863,7 +863,8 @@ DEFUN ("thread-signal", Fthread_signal, Sthread_signal, 3, 3, 0, > This acts like `signal', but arranges for the signal to be raised > in THREAD. If THREAD is the current thread, acts just like `signal'. > This will interrupt a blocked call to `mutex-lock', `condition-wait', > -or `thread-join' in the target thread. */) > +or `thread-join' in the target thread. > +Signals to the main thread are ignored quietly. */) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ That's not really accurate, is it? ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 17:44 ` Eli Zaretskii @ 2018-08-30 19:30 ` Michael Albinus 2018-09-02 17:58 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-08-30 19:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gazally, 32502 Eli Zaretskii <eliz@gnu.org> writes: >> +If @var{thread} is the main thread, the signal is not propagated >> +there. Instead, it is shown as message in the main thread. > > Maybe I'm missing something, but where's the code which shows this > message? thread-handle-event of thread.el. >> @@ -863,7 +863,8 @@ DEFUN ("thread-signal", Fthread_signal, Sthread_signal, 3, 3, 0, >> This acts like `signal', but arranges for the signal to be raised >> in THREAD. If THREAD is the current thread, acts just like `signal'. >> This will interrupt a blocked call to `mutex-lock', `condition-wait', >> -or `thread-join' in the target thread. */) >> +or `thread-join' in the target thread. >> +Signals to the main thread are ignored quietly. */) > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > That's not really accurate, is it? Oh, this is from my first attempt. Fixed. I've committed this to the master. Let's see how it goes. Gemini, I've stolen the frame of your thread.el from the scratch/list-threads branch. You will merge your code there, I guess. I'm a little bit undecided, whether thread events shall be restricted to signaling the main thread with error messages. Could be used for other purposes as well. Let's see. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 19:30 ` Michael Albinus @ 2018-09-02 17:58 ` Michael Albinus 2018-09-02 20:03 ` Gemini Lasswell 0 siblings, 1 reply; 42+ messages in thread From: Michael Albinus @ 2018-09-02 17:58 UTC (permalink / raw) To: gazally; +Cc: 32502 Michael Albinus <michael.albinus@gmx.de> writes: Hi Gemini, > I've committed this to the master. Let's see how it goes. Does this work for you? In this case, I'd like to close the bug. Or do you need something else? Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-09-02 17:58 ` Michael Albinus @ 2018-09-02 20:03 ` Gemini Lasswell 2018-09-02 20:50 ` Michael Albinus 0 siblings, 1 reply; 42+ messages in thread From: Gemini Lasswell @ 2018-09-02 20:03 UTC (permalink / raw) To: Michael Albinus; +Cc: 32502 Michael Albinus <michael.albinus@gmx.de> writes: >> I've committed this to the master. Let's see how it goes. > > Does this work for you? In this case, I'd like to close the bug. Or do > you need something else? Hi Michael, I tried this in the thread-safe-tramp branch and it fixes the problem. Thanks, Gemini ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-09-02 20:03 ` Gemini Lasswell @ 2018-09-02 20:50 ` Michael Albinus 0 siblings, 0 replies; 42+ messages in thread From: Michael Albinus @ 2018-09-02 20:50 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502-done Version: 27.1 Gemini Lasswell <gazally@runbox.com> writes: > Hi Michael, Hi Gemini, > I tried this in the thread-safe-tramp branch and it fixes the problem. Thanks, I'm closing the bug. > Thanks, > Gemini Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 16:48 ` Michael Albinus 2018-08-30 17:44 ` Eli Zaretskii @ 2018-08-30 19:29 ` Gemini Lasswell 2018-08-30 19:37 ` Michael Albinus 2018-08-31 6:52 ` Eli Zaretskii 1 sibling, 2 replies; 42+ messages in thread From: Gemini Lasswell @ 2018-08-30 19:29 UTC (permalink / raw) To: Michael Albinus; +Cc: 32502 Michael Albinus <michael.albinus@gmx.de> writes: > Appended is a first implementation. Comments? I don't understand why this is so complicated. Why not just have the thread show a message, instead of having it send a signal which gets translated into an event that makes the main thread show a message? Also, if we eventually implement one of the proposals in emacs-devel to allow threads other than the main one to accept keyboard input, then there would be no guarantee that putting the event in the keyboard buffer would get it to the main thread. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 19:29 ` Gemini Lasswell @ 2018-08-30 19:37 ` Michael Albinus 2018-08-31 6:52 ` Eli Zaretskii 1 sibling, 0 replies; 42+ messages in thread From: Michael Albinus @ 2018-08-30 19:37 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502 Gemini Lasswell <gazally@runbox.com> writes: > I don't understand why this is so complicated. Why not just have the > thread show a message, instead of having it send a signal which gets > translated into an event that makes the main thread show a message? With thread-handle-event, the main thread could decide to react on the signal/event. > Also, if we eventually implement one of the proposals in emacs-devel to > allow threads other than the main one to accept keyboard input, then > there would be no guarantee that putting the event in the keyboard > buffer would get it to the main thread. We'll see. The event-based implementation was easy to do; it would also be easy to change. Best regards, Michael. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-30 19:29 ` Gemini Lasswell 2018-08-30 19:37 ` Michael Albinus @ 2018-08-31 6:52 ` Eli Zaretskii 2018-08-31 15:07 ` Gemini Lasswell 1 sibling, 1 reply; 42+ messages in thread From: Eli Zaretskii @ 2018-08-31 6:52 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502, michael.albinus > From: Gemini Lasswell <gazally@runbox.com> > Cc: Eli Zaretskii <eliz@gnu.org>, 32502@debbugs.gnu.org > Date: Thu, 30 Aug 2018 12:29:44 -0700 > > I don't understand why this is so complicated. Why not just have the > thread show a message, instead of having it send a signal which gets > translated into an event that makes the main thread show a message? Because the echo area could be showing something important from the main (or some other) thread, e.g. if the user typed "C-x C-f", but didn't yet finish responding to the request for the file name. Displaying something from another thread will wipe out that interaction's text. By submitting an event to the main thread, we make sure these two interactions will be serialized. > Also, if we eventually implement one of the proposals in emacs-devel to > allow threads other than the main one to accept keyboard input, then > there would be no guarantee that putting the event in the keyboard > buffer would get it to the main thread. I don't think it matters, because it will get to the thread which is reading input events, and that thread will then act on the event. But if it turns out it does matter, we can always tag each even with its target thread or something, and modify the queue handling to only act on events whose target is the current thread. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-31 6:52 ` Eli Zaretskii @ 2018-08-31 15:07 ` Gemini Lasswell 2018-08-31 17:45 ` Eli Zaretskii 0 siblings, 1 reply; 42+ messages in thread From: Gemini Lasswell @ 2018-08-31 15:07 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 32502, michael.albinus Eli Zaretskii <eliz@gnu.org> writes: >> From: Gemini Lasswell <gazally@runbox.com> >> >> I don't understand why this is so complicated. Why not just have the >> thread show a message, instead of having it send a signal which gets >> translated into an event that makes the main thread show a message? > > Because the echo area could be showing something important from the > main (or some other) thread, e.g. if the user typed "C-x C-f", but > didn't yet finish responding to the request for the file name. > Displaying something from another thread will wipe out that > interaction's text. In the feature/tramp-thread-safe branch, main thread prompts already get wiped out by messages from other threads, even in the absence of errors. For example, if you start an asynchronous find-file and type M-x before it finishes, the M-x prompt will be overwritten by messages from Tramp and won't reappear after the find-file finishes, until you type something. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-31 15:07 ` Gemini Lasswell @ 2018-08-31 17:45 ` Eli Zaretskii 0 siblings, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-08-31 17:45 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502, michael.albinus > From: Gemini Lasswell <gazally@runbox.com> > Cc: 32502@debbugs.gnu.org, michael.albinus@gmx.de > Date: Fri, 31 Aug 2018 08:07:55 -0700 > > > Because the echo area could be showing something important from the > > main (or some other) thread, e.g. if the user typed "C-x C-f", but > > didn't yet finish responding to the request for the file name. > > Displaying something from another thread will wipe out that > > interaction's text. > > In the feature/tramp-thread-safe branch, main thread prompts already get > wiped out by messages from other threads, even in the absence of errors. Which is why we are having the discussion on emacs-devel trying to figure out how to avoid that. Displaying an error message is a simpler problem, because it doesn't require any response. ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 18:46 ` Eli Zaretskii 2018-08-22 19:08 ` Eli Zaretskii @ 2018-08-22 21:12 ` Gemini Lasswell 2018-08-23 14:01 ` Eli Zaretskii 1 sibling, 1 reply; 42+ messages in thread From: Gemini Lasswell @ 2018-08-22 21:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 32502 Eli Zaretskii <eliz@gnu.org> writes: > In frame #2, which one of these 2 conditions caused the abort: > > if (gc_in_progress || waiting_for_input) > emacs_abort (); > And in frame #4, what is current_thread->error_symbol? > > Thanks. (gdb) p gc_in_progress $1 = false (gdb) p waiting_for_input $2 = true (gdb) up 4 #4 0x00000000005d5555 in post_acquire_global_lock (self=self@entry=0xc19320 <main_thread>) at thread.c:93 93 Fsignal (sym, data); (gdb) p current_thread->error_symbol $3 = XIL(0) (gdb) pr (gdb) pp current_thread->error_symbol (gdb) p current_thread->error_symbol $4 = XIL(0) (gdb) xpr Lisp_Symbol $5 = (struct Lisp_Symbol *) 0xbf5420 <lispsym> "nil" ^ permalink raw reply [flat|nested] 42+ messages in thread
* bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs 2018-08-22 21:12 ` Gemini Lasswell @ 2018-08-23 14:01 ` Eli Zaretskii 0 siblings, 0 replies; 42+ messages in thread From: Eli Zaretskii @ 2018-08-23 14:01 UTC (permalink / raw) To: Gemini Lasswell; +Cc: 32502 > From: Gemini Lasswell <gazally@runbox.com> > Cc: 32502@debbugs.gnu.org > Date: Wed, 22 Aug 2018 14:12:18 -0700 > > Eli Zaretskii <eliz@gnu.org> writes: > > > In frame #2, which one of these 2 conditions caused the abort: > > > > if (gc_in_progress || waiting_for_input) > > emacs_abort (); > > > And in frame #4, what is current_thread->error_symbol? > > > > Thanks. > > (gdb) p gc_in_progress > $1 = false > (gdb) p waiting_for_input > $2 = true > (gdb) up 4 > #4 0x00000000005d5555 in post_acquire_global_lock (self=self@entry=0xc19320 <main_thread>) at thread.c:93 > 93 Fsignal (sym, data); > (gdb) p current_thread->error_symbol > $3 = XIL(0) > (gdb) pr > (gdb) pp current_thread->error_symbol > (gdb) p current_thread->error_symbol > $4 = XIL(0) > (gdb) xpr > Lisp_Symbol > $5 = (struct Lisp_Symbol *) 0xbf5420 <lispsym> > "nil" Thanks. So my assumption was true: the main thread is signaled while waiting for input. Perhaps we should disallow that. ^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2018-09-02 20:50 UTC | newest] Thread overview: 42+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-08-22 18:19 bug#32502: 27.0.50; Tramp; C-g during asynchronous remote find-file kills Emacs Gemini Lasswell 2018-08-22 18:46 ` Eli Zaretskii 2018-08-22 19:08 ` Eli Zaretskii 2018-08-22 19:23 ` Michael Albinus 2018-08-25 10:53 ` Michael Albinus 2018-08-25 12:42 ` Eli Zaretskii 2018-08-25 15:52 ` Michael Albinus 2018-08-25 16:07 ` Eli Zaretskii 2018-08-26 13:50 ` Gemini Lasswell 2018-08-30 9:24 ` Michael Albinus 2018-08-30 13:23 ` Eli Zaretskii 2018-08-30 13:28 ` Michael Albinus 2018-08-25 21:53 ` Gemini Lasswell 2018-08-26 14:12 ` Eli Zaretskii 2018-08-30 7:19 ` Michael Albinus 2018-08-30 12:34 ` Michael Albinus 2018-08-29 16:01 ` Michael Albinus 2018-08-29 16:23 ` Eli Zaretskii 2018-08-29 16:46 ` Michael Albinus 2018-08-29 17:03 ` Eli Zaretskii 2018-08-29 17:15 ` Michael Albinus 2018-08-29 20:22 ` Michael Albinus 2018-08-29 20:57 ` Michael Albinus 2018-08-30 2:36 ` Eli Zaretskii 2018-08-30 7:09 ` Michael Albinus 2018-08-30 13:18 ` Eli Zaretskii 2018-08-30 13:32 ` Michael Albinus 2018-08-30 13:51 ` Eli Zaretskii 2018-08-30 13:59 ` Michael Albinus 2018-08-30 16:48 ` Michael Albinus 2018-08-30 17:44 ` Eli Zaretskii 2018-08-30 19:30 ` Michael Albinus 2018-09-02 17:58 ` Michael Albinus 2018-09-02 20:03 ` Gemini Lasswell 2018-09-02 20:50 ` Michael Albinus 2018-08-30 19:29 ` Gemini Lasswell 2018-08-30 19:37 ` Michael Albinus 2018-08-31 6:52 ` Eli Zaretskii 2018-08-31 15:07 ` Gemini Lasswell 2018-08-31 17:45 ` Eli Zaretskii 2018-08-22 21:12 ` Gemini Lasswell 2018-08-23 14:01 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).