diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2017-02-01 15:18:44 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2017-02-01 15:23:19 -0800 |
commit | b4c9f9120d8b0da0593f2fbde69b40374f56451d (patch) | |
tree | 8f40be80730a41e83e58e0632ff539ac752eb453 | |
parent | b01ac672be1277833964d2d53f6dd26560c70343 (diff) | |
download | emacs-b4c9f9120d8b0da0593f2fbde69b40374f56451d.tar.gz |
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.
-rw-r--r-- | src/callproc.c | 3 | ||||
-rw-r--r-- | src/fns.c | 32 | ||||
-rw-r--r-- | src/indent.c | 6 | ||||
-rw-r--r-- | src/lisp.h | 8 | ||||
-rw-r--r-- | src/search.c | 57 | ||||
-rw-r--r-- | src/syntax.c | 34 | ||||
-rw-r--r-- | src/sysdep.c | 10 |
7 files changed, 70 insertions, 80 deletions
diff --git a/src/callproc.c b/src/callproc.c index 710174c46b0..84324c48dcf 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -198,7 +198,10 @@ call_process_cleanup (Lisp_Object buffer) { kill (-synch_process_pid, SIGINT); message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); + + /* This will quit on C-g. */ wait_for_termination (synch_process_pid, 0, 1); + synch_process_pid = 0; message1 ("Waiting for process to die...done"); } diff --git a/src/fns.c b/src/fns.c index 41c0c5856b4..ac7c1f265a4 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1389,7 +1389,7 @@ The value is actually the tail of LIST whose car is ELT. */) { if (! NILP (Fequal (elt, XCAR (tail)))) return tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1406,7 +1406,7 @@ The value is actually the tail of LIST whose car is ELT. */) { if (EQ (XCAR (tail), elt)) return tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1427,7 +1427,7 @@ The value is actually the tail of LIST whose car is ELT. */) Lisp_Object tem = XCAR (tail); if (FLOATP (tem) && internal_equal (elt, tem, 0, 0, Qnil)) return tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1445,7 +1445,7 @@ Elements of LIST that are not conses are ignored. */) { if (CONSP (XCAR (tail)) && EQ (XCAR (XCAR (tail)), key)) return XCAR (tail); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1476,7 +1476,7 @@ The value is actually the first element of LIST whose car equals KEY. */) if (CONSP (car) && (EQ (XCAR (car), key) || !NILP (Fequal (XCAR (car), key)))) return car; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1509,7 +1509,7 @@ The value is actually the first element of LIST whose cdr is KEY. */) { if (CONSP (XCAR (tail)) && EQ (XCDR (XCAR (tail)), key)) return XCAR (tail); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1528,7 +1528,7 @@ The value is actually the first element of LIST whose cdr equals KEY. */) if (CONSP (car) && (EQ (XCDR (car), key) || !NILP (Fequal (XCDR (car), key)))) return car; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, list); return Qnil; @@ -1684,7 +1684,7 @@ changing the value of a sequence `foo'. */) } else prev = tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, seq); } @@ -1712,7 +1712,7 @@ This function may destructively modify SEQ to produce the value. */) next = XCDR (tail); Fsetcdr (tail, prev); prev = tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, seq); seq = prev; @@ -1759,7 +1759,7 @@ See also the function `nreverse', which is used more often. */) for (new = Qnil; CONSP (seq); seq = XCDR (seq)) { new = Fcons (XCAR (seq), new); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (seq, seq); } @@ -2062,7 +2062,7 @@ The PLIST is modified by side effects. */) } prev = tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } Lisp_Object newcell = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev)))); @@ -2100,7 +2100,7 @@ one of the properties on the list. */) { if (! NILP (Fequal (prop, XCAR (tail)))) return XCAR (XCDR (tail)); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } CHECK_LIST_END (tail, prop); @@ -2130,7 +2130,7 @@ The PLIST is modified by side effects. */) } prev = tail; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } Lisp_Object newcell = list2 (prop, val); if (NILP (prev)) @@ -2210,7 +2210,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props, unsigned short int quit_count = 0; tail_recurse: - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); if (EQ (o1, o2)) return 1; if (XTYPE (o1) != XTYPE (o2)) @@ -2419,7 +2419,7 @@ usage: (nconc &rest LISTS) */) { tail = tem; tem = XCDR (tail); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } while (CONSP (tem)); @@ -2848,7 +2848,7 @@ The value is actually the tail of PLIST whose car is PROP. */) { plist = XCDR (plist); plist = CDR (plist); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } return plist; } diff --git a/src/indent.c b/src/indent.c index aff14abfd20..f630ebb847c 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1215,7 +1215,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, while (true) { - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); while (pos == next_boundary) { @@ -1282,7 +1282,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, pos_byte = CHAR_TO_BYTE (pos); } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } /* Handle right margin. */ @@ -1605,7 +1605,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, pos = find_before_next_newline (pos, to, 1, &pos_byte); if (pos < to) INC_BOTH (pos, pos_byte); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } while (pos < to && indented_beyond_p (pos, pos_byte, 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; diff --git a/src/search.c b/src/search.c index 084adda097b..33cb02aa7af 100644 --- a/src/search.c +++ b/src/search.c @@ -99,6 +99,25 @@ matcher_overflow (void) error ("Stack overflow in regexp matcher"); } +static void +freeze_buffer_relocation (void) +{ +#ifdef REL_ALLOC + /* Prevent ralloc.c from relocating the current buffer while + searching it. */ + r_alloc_inhibit_buffer_relocation (1); + record_unwind_protect_int (r_alloc_inhibit_buffer_relocation, 0); +#endif +} + +static void +thaw_buffer_relocation (void) +{ +#ifdef REL_ALLOC + unbind_to (SPECPDL_INDEX () - 1, Qnil); +#endif +} + /* Compile a regexp and signal a Lisp error if anything goes wrong. PATTERN is the pattern to compile. CP is the place to put the result. @@ -300,19 +319,13 @@ looking_at_1 (Lisp_Object string, bool posix) re_match_object = Qnil; -#ifdef REL_ALLOC - /* Prevent ralloc.c from relocating the current buffer while - searching it. */ - r_alloc_inhibit_buffer_relocation (1); -#endif + freeze_buffer_relocation (); i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2, PT_BYTE - BEGV_BYTE, (NILP (Vinhibit_changing_match_data) ? &search_regs : NULL), ZV_BYTE - BEGV_BYTE); -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif + thaw_buffer_relocation (); if (i == -2) matcher_overflow (); @@ -553,16 +566,10 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, } buf = compile_pattern (regexp, 0, Qnil, 0, multibyte); -#ifdef REL_ALLOC - /* Prevent ralloc.c from relocating the current buffer while - searching it. */ - r_alloc_inhibit_buffer_relocation (1); -#endif + freeze_buffer_relocation (); len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, pos_byte, NULL, limit_byte); -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif + thaw_buffer_relocation (); return len; } @@ -1204,11 +1211,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, } re_match_object = Qnil; -#ifdef REL_ALLOC - /* Prevent ralloc.c from relocating the current buffer while - searching it. */ - r_alloc_inhibit_buffer_relocation (1); -#endif + freeze_buffer_relocation (); while (n < 0) { @@ -1250,9 +1253,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, } else { -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif + thaw_buffer_relocation (); return (n); } n++; @@ -1295,17 +1296,13 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, } else { -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif + thaw_buffer_relocation (); return (0 - n); } n--; maybe_quit (); } -#ifdef REL_ALLOC - r_alloc_inhibit_buffer_relocation (0); -#endif + thaw_buffer_relocation (); return (pos); } else /* non-RE case */ diff --git a/src/syntax.c b/src/syntax.c index 06fe50b866b..7aa43e6e5c7 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -593,7 +593,6 @@ static ptrdiff_t find_defun_start (ptrdiff_t pos, ptrdiff_t pos_byte) { ptrdiff_t opoint = PT, opoint_byte = PT_BYTE; - unsigned short int quit_count = 0; /* Use previous finding, if it's valid and applies to this inquiry. */ if (current_buffer == find_start_buffer @@ -636,7 +635,6 @@ find_defun_start (ptrdiff_t pos, ptrdiff_t pos_byte) } /* Move to beg of previous line. */ scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1); - incr_rarely_quit (&quit_count); } /* Record what we found, for the next try. */ @@ -725,7 +723,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, that determines quote parity to the comment-end. */ while (from != stop) { - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); ptrdiff_t temp_byte; int prev_syntax; @@ -954,7 +952,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, defun_start_byte = CHAR_TO_BYTE (defun_start); } } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } while (defun_start < comment_end); @@ -2386,7 +2384,7 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, nesting++; } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } *charpos_ptr = from; *bytepos_ptr = from_byte; @@ -2460,7 +2458,7 @@ between them, return t; otherwise return nil. */) INC_BOTH (from, from_byte); UPDATE_SYNTAX_TABLE_FORWARD (from); } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } while (code == Swhitespace || (code == Sendcomment && c == '\n')); @@ -2544,7 +2542,7 @@ between them, return t; otherwise return nil. */) } else if (from == stop) break; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } if (fence_found == 0) { @@ -2592,7 +2590,7 @@ between them, return t; otherwise return nil. */) return Qnil; } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } count1++; @@ -2648,7 +2646,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) { while (from < stop) { - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); bool comstart_first, prefix; int syntax, other_syntax; UPDATE_SYNTAX_TABLE_FORWARD (from); @@ -2717,7 +2715,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) goto done; } INC_BOTH (from, from_byte); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } goto done; @@ -2789,7 +2787,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) if (c_code == Scharquote || c_code == Sescape) INC_BOTH (from, from_byte); INC_BOTH (from, from_byte); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } INC_BOTH (from, from_byte); if (!depth && sexpflag) goto done; @@ -2815,7 +2813,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) { while (from > stop) { - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); DEC_BOTH (from, from_byte); UPDATE_SYNTAX_TABLE_BACKWARD (from); c = FETCH_CHAR_AS_MULTIBYTE (from_byte); @@ -2891,7 +2889,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) default: goto done2; } DEC_BOTH (from, from_byte); - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } goto done2; @@ -2954,7 +2952,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) if (syntax_multibyte (c, multibyte_symbol_p) == code) break; } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } if (code == Sstring_fence && !depth && sexpflag) goto done2; break; @@ -2975,7 +2973,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag) == Sstring)) break; } - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } if (!depth && sexpflag) goto done2; break; @@ -3229,7 +3227,7 @@ do { prev_from = from; \ while (from < end) { - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); INC_FROM; if ((from < end) @@ -3286,7 +3284,7 @@ do { prev_from = from; \ goto symdone; } INC_FROM; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } symdone: curlevel->prev = curlevel->last; @@ -3397,7 +3395,7 @@ do { prev_from = from; \ break; } INC_FROM; - incr_rarely_quit (&quit_count); + rarely_quit (++quit_count); } } string_end: diff --git a/src/sysdep.c b/src/sysdep.c index 4155c205712..91b2a5cb943 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2508,12 +2508,12 @@ emacs_close (int fd) #endif /* Read from FD to a buffer BUF with size NBYTE. - If interrupted, either quit or retry the read. - Process any quits and pending signals immediately if INTERRUPTIBLE. + If interrupted, process any quits and pending signals immediately + if INTERRUPTIBLE, and then retry the read unless quitting. Return the number of bytes read, which might be less than NBYTE. On error, set errno to a value other than EINTR, and return -1. */ static ptrdiff_t -emacs_nointr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible) +emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible) { ssize_t result; @@ -2537,14 +2537,14 @@ emacs_nointr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible) ptrdiff_t emacs_read (int fd, void *buf, ptrdiff_t nbyte) { - return emacs_nointr_read (fd, buf, nbyte, false); + return emacs_intr_read (fd, buf, nbyte, false); } /* Like emacs_read, but also process quits and pending signals. */ ptrdiff_t emacs_read_quit (int fd, void *buf, ptrdiff_t nbyte) { - return emacs_nointr_read (fd, buf, nbyte, true); + return emacs_intr_read (fd, buf, nbyte, true); } /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if |