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.
This commit is contained in:
parent
b01ac672be
commit
b4c9f9120d
7 changed files with 70 additions and 80 deletions
|
@ -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");
|
||||
}
|
||||
|
|
32
src/fns.c
32
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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
57
src/search.c
57
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 */
|
||||
|
|
34
src/syntax.c
34
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:
|
||||
|
|
10
src/sysdep.c
10
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
|
||||
|
|
Loading…
Add table
Reference in a new issue