From a727a0303eb34858389cb4331944e0e63411f2ff Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 31 Jan 2017 08:29:02 -0800 Subject: * src/alloc.c, src/lisp.h: Fix minor glitches in recent changes. --- src/lisp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lisp.h') diff --git a/src/lisp.h b/src/lisp.h index 91c430fe98d..58e22889889 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1995,8 +1995,8 @@ struct Lisp_Hash_Table hash table size to reduce collisions. */ Lisp_Object index; - /* Non-nil if the table can be purecopied. Any changes the table after - purecopy will result in an error. */ + /* Non-nil if the table can be purecopied. The table cannot be + changed afterwards. */ Lisp_Object pure; /* Only the fields above are traced normally by the GC. The ones below -- cgit v1.2.1 From 33be50037c2b4cdb002538534e9915c6bad253b7 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:43 -0800 Subject: Remove immediate_quit. The old code that sets and clears immediate_quit was ineffective except when Emacs is running in terminal mode, and has problematic race conditions anyway, so remove it. This will introduce some hangs when Emacs runs in terminal mode, and these hangs should be fixed in followup patches. * src/keyboard.c (immediate_quit): Remove. All uses removed. --- src/lisp.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/lisp.h') diff --git a/src/lisp.h b/src/lisp.h index 58e22889889..a18e4da1cfd 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3131,11 +3131,6 @@ extern Lisp_Object memory_signal_data; impossible, of course. But it is very desirable to avoid creating loops where maybe_quit is impossible. - Exception: if you set immediate_quit, the handler that responds to - the C-g does the quit itself. This is a good thing to do around a - loop that has no side effects and (in particular) cannot call - arbitrary Lisp code. - If quit-flag is set to `kill-emacs' the SIGINT handler has received a request to exit Emacs when it is safe to do. @@ -4348,9 +4343,6 @@ extern char my_edata[]; extern char my_endbss[]; extern char *my_endbss_static; -/* True means ^G can quit instantly. */ -extern bool immediate_quit; - extern void *xmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); extern void *xzalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); extern void *xrealloc (void *, size_t) ATTRIBUTE_ALLOC_SIZE ((2)); -- cgit v1.2.1 From b01ac672be1277833964d2d53f6dd26560c70343 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:44 -0800 Subject: Revamp quitting and fix infloops This fixes some infinite loops that cannot be quitted out of, e.g., (defun foo () (nth most-positive-fixnum '#1=(1 . #1#))) when byte-compiled and when run under X. See: http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00577.html This also attempts to keep the performance improvements I recently added, as much as possible under the constraint that the infloops must be caught. In some cases this fixes infloop bugs recently introduced when I removed immediate_quit. * src/alloc.c (Fmake_list): Use rarely_quit, not maybe_quit, for speed in the usual case. * src/bytecode.c (exec_byte_code): * src/editfns.c (Fcompare_buffer_substrings): * src/fns.c (Fnthcdr): * src/syntax.c (scan_words, skip_chars, skip_syntaxes) (Fbackward_prefix_chars): Use rarely_quit so that users can C-g out of long loops. * src/callproc.c (call_process_cleanup, call_process): * src/fileio.c (read_non_regular, Finsert_file_contents): * src/indent.c (compute_motion): * src/syntax.c (scan_words, Fforward_comment): Remove now-unnecessary maybe_quit calls. * src/callproc.c (call_process): * src/doc.c (get_doc_string, Fsnarf_documentation): * src/fileio.c (Fcopy_file, read_non_regular, Finsert_file_contents): * src/lread.c (safe_to_load_version): * src/sysdep.c (system_process_attributes) [GNU_LINUX]: Use emacs_read_quit instead of emacs_read in places where C-g handling is safe. * src/eval.c (maybe_quit): Move comment here from lisp.h. * src/fileio.c (Fcopy_file, e_write): Use emacs_write_quit instead of emacs_write_sig in places where C-g handling is safe. * src/filelock.c (create_lock_file): Use emacs_write, not plain write, as emacs_write no longer has a problem. (read_lock_data): Use emacs_read, not read, as emacs_read no longer has a problem. * src/fns.c (rarely_quit): Move to lisp.h and rename to incr_rarely_quit. All uses changed.. * src/fns.c (Fmemq, Fmemql, Fassq, Frassq, Fplist_put, Fplist_member): * src/indent.c (compute_motion): * src/syntax.c (find_defun_start, back_comment, forw_comment) (Fforward_comment, scan_lists, scan_sexps_forward): Use incr_rarely_quit so that users can C-g out of long loops. * src/fns.c (Fnconc): Move incr_rarely_quit call to within inner loop, so that it catches C-g there too. * src/keyboard.c (tty_read_avail_input): Remove commented-out and now-obsolete code dealing with interrupts. * src/lisp.h (rarely_quit, incr_rarely_quit): New functions, the latter moved here from fns.c and renamed from rarely_quit. (emacs_read_quit, emacs_write_quit): New decls. * src/search.c (find_newline, search_buffer, find_newline1): Add maybe_quit to catch C-g. * src/sysdep.c (get_child_status): Always invoke maybe_quit if interruptible, so that the caller need not bother. (emacs_nointr_read, emacs_read_quit, emacs_write_quit): New functions. (emacs_read): Rewrite in terms of emacs_nointr_read. Do not handle C-g or signals; that is now for emacs_read_quit. (emacs_full_write): Replace PROCESS_SIGNALS two-way arg with INTERRUPTIBLE three-way arg. All uses changed. --- src/lisp.h | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'src/lisp.h') diff --git a/src/lisp.h b/src/lisp.h index a18e4da1cfd..2d67e7edddb 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3123,24 +3123,36 @@ struct handler extern Lisp_Object memory_signal_data; -/* Check quit-flag and quit if it is non-nil. Typing C-g does not - directly cause a quit; it only sets Vquit_flag. So the program - needs to call maybe_quit at times when it is safe to quit. Every - loop that might run for a long time or might not exit ought to call - maybe_quit at least once, at a safe place. Unless that is - impossible, of course. But it is very desirable to avoid creating - loops where maybe_quit is impossible. - - If quit-flag is set to `kill-emacs' the SIGINT handler has received - a request to exit Emacs when it is safe to do. - - When not quitting, process any pending signals. */ - extern void maybe_quit (void); /* True if ought to quit now. */ #define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) + +/* Heuristic on how many iterations of a tight loop can be safely done + before it's time to do a quit. This must be a power of 2. It + is nice but not necessary for it to equal USHRT_MAX + 1. */ + +enum { QUIT_COUNT_HEURISTIC = 1 << 16 }; + +/* Process a quit rarely, based on a counter COUNT, for efficiency. + "Rarely" means once per QUIT_COUNT_HEURISTIC or per USHRT_MAX + 1 + times, whichever is smaller (somewhat arbitrary, but often faster). */ + +INLINE void +rarely_quit (unsigned short int count) +{ + if (! (count & (QUIT_COUNT_HEURISTIC - 1))) + maybe_quit (); +} + +/* Increment *QUIT_COUNT and rarely quit. */ + +INLINE void +incr_rarely_quit (unsigned short int *quit_count) +{ + rarely_quit (++*quit_count); +} extern Lisp_Object Vascii_downcase_table; extern Lisp_Object Vascii_canon_table; @@ -4216,8 +4228,10 @@ extern int emacs_open (const char *, int, int); extern int emacs_pipe (int[2]); extern int emacs_close (int); extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); +extern ptrdiff_t emacs_read_quit (int, void *, ptrdiff_t); extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t); extern ptrdiff_t emacs_write_sig (int, void const *, ptrdiff_t); +extern ptrdiff_t emacs_write_quit (int, void const *, ptrdiff_t); extern void emacs_perror (char const *); extern void unlock_all_files (void); -- cgit v1.2.1 From b4c9f9120d8b0da0593f2fbde69b40374f56451d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 1 Feb 2017 15:18:44 -0800 Subject: Fix quitting bug when buffers are frozen Problem noted by Eli Zaretskii in: http://lists.gnu.org/archive/html/emacs-devel/2017-01/msg00721.html This patch also fixes some other issues in that report. * src/lisp.h (incr_rarely_quit): Remove. All callers changed to use rarely_quit directly. * src/search.c (freeze_buffer_relocation) (thaw_buffer_relocation): New functions. (looking_at_1, fast_looking_at, search_buffer): Use them to fix bug when quitting when buffers are frozen. * src/sysdep.c (emacs_intr_read): Rename from emacs_nointr_read. All uses changed. --- src/lisp.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/lisp.h') diff --git a/src/lisp.h b/src/lisp.h index 2d67e7edddb..1ac38164c27 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3145,14 +3145,6 @@ rarely_quit (unsigned short int count) if (! (count & (QUIT_COUNT_HEURISTIC - 1))) maybe_quit (); } - -/* Increment *QUIT_COUNT and rarely quit. */ - -INLINE void -incr_rarely_quit (unsigned short int *quit_count) -{ - rarely_quit (++*quit_count); -} extern Lisp_Object Vascii_downcase_table; extern Lisp_Object Vascii_canon_table; -- cgit v1.2.1