summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-02-01 15:18:44 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2017-02-01 15:23:19 -0800
commitb4c9f9120d8b0da0593f2fbde69b40374f56451d (patch)
tree8f40be80730a41e83e58e0632ff539ac752eb453
parentb01ac672be1277833964d2d53f6dd26560c70343 (diff)
downloademacs-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.c3
-rw-r--r--src/fns.c32
-rw-r--r--src/indent.c6
-rw-r--r--src/lisp.h8
-rw-r--r--src/search.c57
-rw-r--r--src/syntax.c34
-rw-r--r--src/sysdep.c10
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